VirtualBox

Changeset 49490 in vbox


Ignore:
Timestamp:
Nov 15, 2013 10:09:13 AM (11 years ago)
Author:
vboxsync
Message:

VBoxNetDHCP. split ::init to ::initWithMain and ::initNoMain. The first step to avoid connection to Main when servicing Host-Only and Internal Network. ::initNoMain() drops connection at fist action. The further improvement will be hint from caller (cmdline parameter whether DHCP need consult Main and listen for changes on Host-side).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp

    r49412 r49490  
    105105    void                debugPrintV(int32_t iMinLevel, bool fMsg,  const char *pszFmt, va_list va) const;
    106106    static const char  *debugDhcpName(uint8_t uMsgType);
     107
     108private:
     109    int initNoMain();
     110    int initWithMain();
    107111
    108112protected:
     
    164168
    165169/* DHCP server specific options */
    166 static const RTGETOPTDEF g_aOptionDefs[] =
     170static RTGETOPTDEF g_aOptionDefs[] =
    167171{
    168172  { "--lease-db",       'D',   RTGETOPT_REQ_STRING },
     
    272276
    273277    m_fIgnoreCmdLineParameters = true;
     278
     279    for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
     280        m_vecOptionDefs.push_back(&g_aOptionDefs[i]);
    274281
    275282#if 0 /* enable to hack the code without a mile long argument list. */
     
    324331    switch (rc)
    325332    {
    326             /* Begin config. */
    327         case 'b':
    328             CmdParameterll.push_back(prm);
    329             break;
    330 
    331333        case 'l':
    332334        case 'u':
    333         case 'm':
    334         case 'g':
    335             prm.strValue = std::string(Val.psz);
     335        case 'g':
     336        {
     337            char buf[17];
     338            RTStrPrintf(buf, 17, "%RTnaipv4", Val.IPv4Addr.u);
     339            prm.strValue = buf;
    336340            CmdParameterll.push_back(prm);
    337             break;
    338 
    339         case 'D':
     341        }
     342        break;
     343
     344        case 'b': // ignore
     345        case 'D': // ignore
    340346            break;
    341347
     
    346352    }
    347353
    348     return rc;
     354    return VINF_SUCCESS;
    349355}
    350356
     
    364370                                           m_NATNetwork.asOutParam());
    365371
    366     /* This isn't fatal in general case.
    367      * AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    368      */
    369 
    370     ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    371     AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
    372 
    373     /*
    374      * if we have nat netework of the same name
    375      * this is good chance that we are assigned to this network.
    376      */
    377     BOOL fNeedDhcpServer = false;
    378     if (   !m_NATNetwork.isNull()
    379         && SUCCEEDED(m_NATNetwork->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer))
    380         && fNeedDhcpServer)
    381     {
    382         /* 90% we are servicing NAT network */
    383         RTNETADDRIPV4 gateway;
    384         com::Bstr strGateway;
    385         hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam());
    386         AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    387         RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
    388 
    389         confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
    390 
    391         unsigned int i;
    392         unsigned int count_strs;
    393         com::SafeArray<BSTR> strs;
    394         std::map<RTNETADDRIPV4, uint32_t> MapIp4Addr2Off;
    395 
    396         hrc = m_NATNetwork->COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs));
    397         if (   SUCCEEDED(hrc)
    398             && (count_strs = strs.size()))
    399         {
    400             for (i = 0; i < count_strs; ++i)
    401             {
    402                 char szAddr[17];
    403                 RTNETADDRIPV4 ip4addr;
    404                 char *pszTerm;
    405                 uint32_t u32Off;
    406                 com::Utf8Str strLo2Off(strs[i]);
    407                 const char *pszLo2Off = strLo2Off.c_str();
    408 
    409                 RT_ZERO(szAddr);
    410 
    411                 pszTerm = RTStrStr(pszLo2Off, "=");
    412 
    413                 if (   pszTerm
    414                     && (pszTerm - pszLo2Off) <= INET_ADDRSTRLEN)
    415                 {
    416                     memcpy(szAddr, pszLo2Off, (pszTerm - pszLo2Off));
    417                     int rc = RTNetStrToIPv4Addr(szAddr, &ip4addr);
    418                     if (RT_SUCCESS(rc))
    419                     {
    420                         u32Off = RTStrToUInt32(pszTerm + 1);
    421                         if (u32Off != 0)
    422                             MapIp4Addr2Off.insert(
    423                               std::map<RTNETADDRIPV4,uint32_t>::value_type(ip4addr, u32Off));
    424                     }
    425                 }
    426             }
    427         }
    428 
    429         strs.setNull();
    430         ComPtr<IHost> host;
    431         if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam())))
    432         {
    433             if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))))
    434             {
    435                 RTNETADDRIPV4 addr;
    436                 confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
    437                 int rc;
    438                 for (i = 0; i < strs.size(); ++i)
    439                 {
    440                     rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
    441                     if (RT_SUCCESS(rc))
    442                     {
    443                         if (addr.au8[0] == 127)
    444                         {
    445                             if (MapIp4Addr2Off[addr] != 0)
    446                             {
    447                                 addr.u = RT_H2N_U32(RT_N2H_U32(m_Ipv4Address.u & m_Ipv4Netmask.u)
    448                                                     + MapIp4Addr2Off[addr]);
    449                             }
    450                             else
    451                                 continue;
    452                         }
    453 
    454                         confManager->addToAddressList(RTNET_DHCP_OPT_DNS, addr);
    455                     }
    456                 }
    457             }
    458 
    459             strs.setNull();
    460 #if 0
    461             if (SUCCEEDED(host->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(strs))))
    462             {
    463                 /* XXX: todo. */;
    464             }
    465             strs.setNull();
    466 #endif
    467             com::Bstr domain;
    468             if (SUCCEEDED(host->COMGETTER(DomainName)(domain.asOutParam())))
    469                 confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, std::string(com::Utf8Str(domain).c_str()));
    470 
    471 
    472         }
    473        
    474     }
    475 
     372
     373    bool fNoMain = m_NATNetwork.isNull();
     374    int rc;
    476375    NetworkManager *netManager = NetworkManager::getNetworkManager();
    477376
     
    480379    netManager->setOurMac(m_MacAddress);
    481380
    482     /* Configuration fetching */
    483     if (m_fIgnoreCmdLineParameters)
    484     {
    485         /* just fetch option array and add options to config */
    486         /* per VM-settings ???
    487          *
    488          * - we have vms with attached adapters with known mac-addresses
    489          * - mac-addresses might be changed as well as names, how keep our config cleaned ????
    490          */
    491         com::SafeArray<BSTR> sf;
    492         hrc = m_DhcpServer->COMGETTER(GlobalOptions)(ComSafeArrayAsOutParam(sf));
    493         AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    494 
    495 #if 0
    496         for (int i = 0; i < sf.size(); ++i)
    497         {
    498             RTPrintf("%d: %s\n", i, com::Utf8Str(sf[i]).c_str());
    499         }
    500 
    501 #endif
    502         com::Bstr strUpperIp, strLowerIp;
    503 
    504         RTNETADDRIPV4 LowerAddress;
    505         RTNETADDRIPV4 UpperAddress;
    506 
    507         hrc = m_DhcpServer->COMGETTER(UpperIP)(strUpperIp.asOutParam());
    508         AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    509         RTNetStrToIPv4Addr(com::Utf8Str(strUpperIp).c_str(), &UpperAddress);
    510 
    511 
    512         hrc = m_DhcpServer->COMGETTER(LowerIP)(strLowerIp.asOutParam());
    513         AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    514         RTNetStrToIPv4Addr(com::Utf8Str(strLowerIp).c_str(), &LowerAddress);
    515 
    516         RTNETADDRIPV4 networkId;
    517         networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
    518         std::string name = std::string("default");
    519 
    520         NetworkConfigEntity *pCfg = confManager->addNetwork(unconst(g_RootConfig),
    521                                                             networkId,
    522                                                             m_Ipv4Netmask,
    523                                                             LowerAddress,
    524                                                             UpperAddress);
    525 
    526         com::Bstr bstr;
    527         hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
    528         std::string strXmlLeaseFile(com::Utf8StrFmt("%ls%c%s.leases",
    529                                                     bstr.raw(), RTPATH_DELIMITER, m_Network.c_str()).c_str());
    530         confManager->loadFromFile(strXmlLeaseFile);
    531 
    532     } /* if(m_fIgnoreCmdLineParameters) */
     381    if (fNoMain)
     382        rc = initNoMain();
    533383    else
    534     {
    535         CmdParameterIterator it;
    536 
    537         RTNETADDRIPV4 networkId;
    538         networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
    539         RTNETADDRIPV4 netmask = m_Ipv4Netmask;
    540         RTNETADDRIPV4 LowerAddress;
    541         RTNETADDRIPV4 UpperAddress;
    542 
    543         LowerAddress = networkId;
    544         UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
    545 
    546         int idx = 0;
    547         char name[64];
    548 
    549 
    550         for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
    551         {
    552             idx++;
    553             RTStrPrintf(name, RT_ELEMENTS(name), "network-%d", idx);
    554             std::string strname(name);
    555 
    556             switch(it->Key)
    557             {
    558                 case 'b':
    559                     /* config */
    560                     NetworkConfigEntity(strname,
    561                                         g_RootConfig,
    562                                         g_AnyClient,
    563                                         5,
    564                                         networkId,
    565                                         netmask,
    566                                         LowerAddress,
    567                                         UpperAddress);
    568                 case 'l':
    569                 case 'u':
    570                 case 'm':
    571                 case 'g':
    572                     /* XXX: TBD */
    573                     break;
    574             }
    575         }
    576     }
     384        rc = initWithMain();
     385
     386    AssertRCReturn(rc, rc);
     387
    577388    return VINF_SUCCESS;
    578389}
     
    709520bool VBoxNetDhcp::handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb)
    710521{
    711 
    712     /* let's main first */
    713     if (!m_DhcpServer.isNull())
    714     {
    715 #if 0
    716         HRESULT hrc;
    717         com::SafeArray<BSTR> sf;
    718         hrc = m_DhcpServer->GetMacOptions(com::BstrFmt("%02X%02X%02X%02X%02X%02X",
    719                                                   pDhcpMsg->bp_chaddr.Mac.au8[0],
    720                                                   pDhcpMsg->bp_chaddr.Mac.au8[1],
    721                                                   pDhcpMsg->bp_chaddr.Mac.au8[2],
    722                                                   pDhcpMsg->bp_chaddr.Mac.au8[3],
    723                                                   pDhcpMsg->bp_chaddr.Mac.au8[4],
    724                                                   pDhcpMsg->bp_chaddr.Mac.au8[5]).raw(),
    725                                           ComSafeArrayAsOutParam(sf));
    726         if (SUCCEEDED(hrc))
    727         {
    728             /* XXX: per-host configuration */
    729         }
    730 #endif
    731         RawOption opt;
    732         memset(&opt, 0, sizeof(RawOption));
    733         /* 1. Find client */
    734         ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    735         Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
    736 
    737         /* 2. Find/Bind lease for client */
    738         Lease lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);
    739         AssertReturn(lease != Lease::NullLease, VINF_SUCCESS);
    740 
    741         int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);
    742 
    743         /* 3. Send of offer */
    744         NetworkManager *networkManager = NetworkManager::getNetworkManager();
    745 
    746         lease.bindingPhase(true);
    747         lease.phaseStart(RTTimeMilliTS());
    748         lease.setExpiration(300); /* 3 min. */
    749         networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
    750     } /* end of if(!m_DhcpServer.isNull()) */
     522    RawOption opt;
     523    memset(&opt, 0, sizeof(RawOption));
     524    /* 1. Find client */
     525    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
     526    Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
     527
     528    /* 2. Find/Bind lease for client */
     529    Lease lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);
     530    AssertReturn(lease != Lease::NullLease, VINF_SUCCESS);
     531
     532    int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);
     533
     534    /* 3. Send of offer */
     535    NetworkManager *networkManager = NetworkManager::getNetworkManager();
     536
     537    lease.bindingPhase(true);
     538    lease.phaseStart(RTTimeMilliTS());
     539    lease.setExpiration(300); /* 3 min. */
     540    networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
    751541
    752542    return VINF_SUCCESS;
     
    941731
    942732
     733int VBoxNetDhcp::initNoMain()
     734{
     735    /* In Host-Only mode we don't need Main. */
     736    com::Shutdown();
     737
     738    CmdParameterIterator it;
     739
     740    RTNETADDRIPV4 networkId;
     741    networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
     742    RTNETADDRIPV4 netmask = m_Ipv4Netmask;
     743
     744    RTNETADDRIPV4 UpperAddress;
     745    RTNETADDRIPV4 LowerAddress = networkId;
     746    UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
     747
     748    for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
     749    {
     750        switch(it->Key)
     751        {
     752            case 'l':
     753                RTNetStrToIPv4Addr(it->strValue.c_str(), &LowerAddress);
     754                break;
     755
     756            case 'u':
     757                RTNetStrToIPv4Addr(it->strValue.c_str(), &UpperAddress);
     758                break;
     759            case 'b':
     760                break;
     761                   
     762        }
     763    }
     764       
     765    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
     766    AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
     767    confManager->addNetwork(unconst(g_RootConfig),
     768                            networkId,
     769                            m_Ipv4Netmask,
     770                            LowerAddress,
     771                            UpperAddress);
     772
     773    return VINF_SUCCESS;
     774}
     775
     776
     777int VBoxNetDhcp::initWithMain()
     778{
     779    BOOL fNeedDhcpServer = false;
     780    if (FAILED(m_NATNetwork->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer)))
     781        return VERR_INTERNAL_ERROR;
     782
     783    if (!fNeedDhcpServer)
     784        return VERR_CANCELLED;
     785
     786    RTNETADDRIPV4 gateway;
     787    com::Bstr strGateway;
     788
     789    HRESULT hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam());
     790    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
     791    RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
     792
     793    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
     794    AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
     795    confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
     796
     797    unsigned int i;
     798    unsigned int count_strs;
     799    com::SafeArray<BSTR> strs;
     800    std::map<RTNETADDRIPV4, uint32_t> MapIp4Addr2Off;
     801
     802    hrc = m_NATNetwork->COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs));
     803    if (   SUCCEEDED(hrc)
     804           && (count_strs = strs.size()))
     805    {
     806        for (i = 0; i < count_strs; ++i)
     807        {
     808            char szAddr[17];
     809            RTNETADDRIPV4 ip4addr;
     810            char *pszTerm;
     811            uint32_t u32Off;
     812            com::Utf8Str strLo2Off(strs[i]);
     813            const char *pszLo2Off = strLo2Off.c_str();
     814
     815            RT_ZERO(szAddr);
     816
     817            pszTerm = RTStrStr(pszLo2Off, "=");
     818
     819            if (   pszTerm
     820                   && (pszTerm - pszLo2Off) <= INET_ADDRSTRLEN)
     821            {
     822                memcpy(szAddr, pszLo2Off, (pszTerm - pszLo2Off));
     823                int rc = RTNetStrToIPv4Addr(szAddr, &ip4addr);
     824                if (RT_SUCCESS(rc))
     825                {
     826                    u32Off = RTStrToUInt32(pszTerm + 1);
     827                    if (u32Off != 0)
     828                        MapIp4Addr2Off.insert(
     829                          std::map<RTNETADDRIPV4,uint32_t>::value_type(ip4addr, u32Off));
     830                }
     831            }
     832        }
     833    }
     834
     835    strs.setNull();
     836    ComPtr<IHost> host;
     837    if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam())))
     838    {
     839        if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))))
     840        {
     841            RTNETADDRIPV4 addr;
     842
     843            confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
     844            int rc;
     845            for (i = 0; i < strs.size(); ++i)
     846            {
     847                rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
     848                if (RT_SUCCESS(rc))
     849                {
     850                    if (addr.au8[0] == 127)
     851                    {
     852                        if (MapIp4Addr2Off[addr] != 0)
     853                        {
     854                            addr.u = RT_H2N_U32(RT_N2H_U32(m_Ipv4Address.u & m_Ipv4Netmask.u)
     855                                                + MapIp4Addr2Off[addr]);
     856                        }
     857                        else
     858                            continue;
     859                    }
     860
     861                    confManager->addToAddressList(RTNET_DHCP_OPT_DNS, addr);
     862                }
     863            }
     864        }
     865
     866        strs.setNull();
     867#if 0
     868        if (SUCCEEDED(host->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(strs))))
     869        {
     870            /* XXX: todo. */;
     871        }
     872        strs.setNull();
     873#endif
     874        com::Bstr domain;
     875        if (SUCCEEDED(host->COMGETTER(DomainName)(domain.asOutParam())))
     876            confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, std::string(com::Utf8Str(domain).c_str()));
     877    }
     878
     879    com::Bstr strUpperIp, strLowerIp;
     880   
     881    RTNETADDRIPV4 LowerAddress;
     882    RTNETADDRIPV4 UpperAddress;
     883
     884    hrc = m_DhcpServer->COMGETTER(UpperIP)(strUpperIp.asOutParam());
     885    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
     886    RTNetStrToIPv4Addr(com::Utf8Str(strUpperIp).c_str(), &UpperAddress);
     887
     888
     889    hrc = m_DhcpServer->COMGETTER(LowerIP)(strLowerIp.asOutParam());
     890    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
     891    RTNetStrToIPv4Addr(com::Utf8Str(strLowerIp).c_str(), &LowerAddress);
     892
     893    RTNETADDRIPV4 networkId;
     894    networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
     895    std::string name = std::string("default");
     896
     897    confManager->addNetwork(unconst(g_RootConfig),
     898                            networkId,
     899                            m_Ipv4Netmask,
     900                            LowerAddress,
     901                            UpperAddress);
     902
     903    com::Bstr bstr;
     904    hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
     905    std::string strXmlLeaseFile(com::Utf8StrFmt("%ls%c%s.leases",
     906                                                bstr.raw(), RTPATH_DELIMITER, m_Network.c_str()).c_str());
     907    confManager->loadFromFile(strXmlLeaseFile);
     908
     909    return VINF_SUCCESS;
     910}
    943911
    944912/**
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