VirtualBox

Changeset 49327 in vbox for trunk


Ignore:
Timestamp:
Oct 30, 2013 4:45:35 AM (11 years ago)
Author:
vboxsync
Message:

NetworkService/DHCP: refactoring:

  1. Client and Lease are use shared data.
  2. data moved to closer to implementations and accessible via accessors.
Location:
trunk/src/VBox/NetworkServices/DHCP
Files:
3 edited

Legend:

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

    r49065 r49327  
    1515#include <VBox/version.h>
    1616
     17#include <VBox/com/string.h>
     18
     19#include <iprt/cpp/xml.h>
     20
    1721#include "../NetLib/VBoxNetLib.h"
     22#include "../NetLib/shared_ptr.h"
    1823
    1924#include <list>
     
    2530
    2631/* types */
    27 class Lease::Data
     32class ClientData
    2833{
    2934public:
    30     Data()
     35    ClientData()
    3136    {
    3237        m_address.u = 0;
    33         m_client = NULL;
     38        m_network.u = 0;
     39        fHasLease = false;
     40        fHasClient = false;
    3441        fBinding = true;
    3542        u64TimestampBindingStarted = 0;
     
    4047
    4148    }
    42     ~Data(){}
     49    ~ClientData(){}
    4350   
     51    /* client information */
    4452    RTNETADDRIPV4 m_address;
    45 
     53    RTNETADDRIPV4 m_network;
     54    RTMAC m_mac;
     55   
     56    bool fHasClient;
     57
     58    /* Lease part */
     59    bool fHasLease;
    4660    /** lease isn't commited */
    4761    bool fBinding;
     
    5771    uint32_t u32BindExpirationPeriod;
    5872
     73    MapOptionId2RawOption options;
     74
    5975    NetworkConfigEntity *pCfg;
    60     Client *m_client;
    6176};
    6277
    6378
     79bool operator== (const Lease& lhs, const Lease& rhs)
     80{
     81    return (lhs.m.get() == rhs.m.get());
     82}
     83
     84
     85bool operator!= (const Lease& lhs, const Lease& rhs)
     86{
     87    return !(lhs == rhs);
     88}
     89
     90
     91bool operator< (const Lease& lhs, const Lease& rhs)
     92{
     93    return (   (lhs.getAddress() < rhs.getAddress())
     94            || (lhs.issued() < rhs.issued()));
     95}
    6496/* consts */
    6597
     
    74106int BaseConfigEntity::match(Client& client, BaseConfigEntity **cfg)
    75107{
    76         int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0);
    77         if (m_children.empty())
     108    int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0);
     109    if (m_children.empty())
     110    {
     111        if (iMatch > 0)
    78112        {
    79             if (iMatch > 0)
     113            *cfg = this;
     114            return iMatch;
     115        }
     116    }
     117    else
     118    {
     119        *cfg = this;
     120        /* XXX: hack */
     121        BaseConfigEntity *matching = this;
     122        int matchingLevel = m_MatchLevel;
     123
     124        for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin();
     125             it != m_children.end();
     126             ++it)
     127        {
     128            iMatch = (*it)->match(client, &matching);
     129            if (iMatch > matchingLevel)
    80130            {
    81                 *cfg = this;
    82                 return iMatch;
     131                *cfg = matching;
     132                matchingLevel = iMatch;
    83133            }
    84134        }
    85         else
    86         {
    87             *cfg = this;
    88             /* XXX: hack */
    89             BaseConfigEntity *matching = this;
    90             int matchingLevel = m_MatchLevel;
    91 
    92             for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin();
    93                  it != m_children.end();
    94                  ++it)
    95             {
    96                 iMatch = (*it)->match(client, &matching);
    97                 if (iMatch > matchingLevel)
    98                 {
    99                     *cfg = matching;
    100                     matchingLevel = iMatch;
    101                 }
    102             }
    103             return matchingLevel;
    104         }
    105         return iMatch;
     135        return matchingLevel;
     136    }
     137    return iMatch;
    106138}
    107139
    108140/* Client */
    109 
    110 Client::Client(const RTMAC& mac)
    111 {
    112     m_mac = mac;
    113     m_lease = NULL;
    114 }
    115 
    116141/* Configs
    117142    NetworkConfigEntity(std::string name,
     
    130155}
    131156
    132 
    133157/* Configuration Manager */
     158struct ConfigurationManager::Data
     159{
     160    Data():fFileExists(false){}
     161
     162    MapLease2Ip4Address  m_allocations;
     163    Ipv4AddressContainer m_nameservers;
     164    Ipv4AddressContainer m_routers;
     165
     166    std::string          m_domainName;
     167    VecClient            m_clients;
     168   
     169    bool                 fFileExists;
     170};
     171   
    134172ConfigurationManager *ConfigurationManager::getConfigurationManager()
    135173{
    136174    if (!g_ConfigurationManager)
     175    {
    137176        g_ConfigurationManager = new ConfigurationManager();
     177        g_ConfigurationManager->init();
     178    }
    138179
    139180    return g_ConfigurationManager;
     
    147188
    148189
    149 Client *ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg)
     190Client ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg)
    150191{
    151192
     
    155196
    156197    fDhcpValid = RTNetIPv4IsDHCPValid(NULL, pDhcpMsg, cbDhcpMsg, &uMsgType);
    157     AssertReturn(fDhcpValid, NULL);
     198    AssertReturn(fDhcpValid, Client::NullClient);
    158199
    159200    LogFlowFunc(("dhcp:mac:%RTmac\n", &pDhcpMsg->bp_chaddr.Mac));
    160201    /* 1st. client IDs */
    161     for ( it = m_clients.begin();
    162          it != m_clients.end();
     202    for ( it = m->m_clients.begin();
     203         it != m->m_clients.end();
    163204         ++it)
    164205    {
    165         if (*(*it) == pDhcpMsg->bp_chaddr.Mac)
     206        if ((*it) == pDhcpMsg->bp_chaddr.Mac)
    166207        {
    167             LogFlowFunc(("client:mac:%RTmac\n",  &(*it)->m_mac));
     208            LogFlowFunc(("client:mac:%RTmac\n",  it->getMacAddress()));
    168209            /* check timestamp that request wasn't expired. */
    169210            return (*it);
     
    171212    }
    172213
    173     if (it == m_clients.end())
     214    if (it == m->m_clients.end())
    174215    {
    175216        /* We hasn't got any session for this client */
    176         m_clients.push_back(new Client(pDhcpMsg->bp_chaddr.Mac));
    177         return m_clients.back();
    178     }
    179 
    180     return NULL;
     217        Client c;
     218        c.initWithMac(pDhcpMsg->bp_chaddr.Mac);
     219        m->m_clients.push_back(c);
     220        return m->m_clients.back();
     221    }
     222
     223    return Client::NullClient;
    181224}
    182225
     
    253296 * We bind lease for client till it continue with it on DHCPREQUEST.
    254297 */
    255 Lease *ConfigurationManager::allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg)
    256 {
    257     /**
    258      * Well, session hasn't get the config.
    259      */
    260     AssertPtrReturn(client, NULL);
    261 
    262     /**
    263      * This mean that client has already bound or commited lease.
    264      * If we've it happens it means that we received DHCPDISCOVER twice.
    265      */
    266     if (client->m_lease)
    267     {
    268         if (client->m_lease->isExpired())
    269             expireLease4Client(client);
    270         else
     298Lease ConfigurationManager::allocateLease4Client(const Client& client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg)
     299{
     300    {
     301        /**
     302         * This mean that client has already bound or commited lease.
     303         * If we've it happens it means that we received DHCPDISCOVER twice.
     304         */
     305        const Lease l = client.lease();
     306        if (l != Lease::NullLease)
    271307        {
    272             AssertReturn(client->m_lease->getAddress().u != 0,NULL);
    273             return client->m_lease;
     308            /* Here we should take lease from the m_allocation which was feed with leases
     309             *  on start
     310             */
     311            if (l.isExpired())
     312            {
     313                expireLease4Client(const_cast<Client&>(client));
     314                if (!l.isExpired())
     315                    return l;
     316            }
     317            else
     318            {
     319                AssertReturn(l.getAddress().u != 0, Lease::NullLease);
     320                return l;
     321            }
    274322        }
    275323    }
     
    277325    RTNETADDRIPV4 hintAddress;
    278326    RawOption opt;
    279     Lease *please = NULL;
    280 
    281327    NetworkConfigEntity *pNetCfg;
    282328
    283     AssertReturn(g_RootConfig->match(*client, (BaseConfigEntity **)&pNetCfg) > 0, NULL);
     329    Client cl(client);
     330    AssertReturn(g_RootConfig->match(cl, (BaseConfigEntity **)&pNetCfg) > 0, Lease::NullLease);
    284331
    285332    /* DHCPDISCOVER MAY contain request address */
     
    295342
    296343    if (   hintAddress.u
    297         && !isAddressTaken(hintAddress, NULL))
    298     {
    299         please = new Lease();
    300         please->init();
    301         please->setConfig(pNetCfg);
    302         please->setClient(client);
    303         client->m_lease = please;
    304         client->m_lease->setAddress(hintAddress);
    305         m_allocations[please] = hintAddress;
    306         return please;
     344        && !isAddressTaken(hintAddress))
     345    {
     346        Lease l(cl);
     347        l.setConfig(pNetCfg);
     348        l.setAddress(hintAddress);
     349        m->m_allocations.insert(MapLease2Ip4AddressPair(l, hintAddress));
     350        return l;
    307351    }
    308352
     
    314358        RTNETADDRIPV4 address;
    315359        address.u = RT_H2N_U32(u32);
    316         if (!isAddressTaken(address, NULL))
     360        if (!isAddressTaken(address))
    317361        {
    318             please = new Lease();
    319             please->init();
    320             please->setConfig(pNetCfg);
    321             please->setClient(client);
    322             please->setAddress(address);
    323 
    324             client->m_lease = please;
    325 
    326             m_allocations[please] = address;
    327             return please;
     362            Lease l(cl);
     363            l.setConfig(pNetCfg);
     364            l.setAddress(address);
     365            m->m_allocations.insert(MapLease2Ip4AddressPair(l, address));
     366            return l;
    328367        }
    329368    }
    330369
    331     return NULL;
    332 }
    333 
    334 
    335 int ConfigurationManager::commitLease4Client(Client *client)
    336 {
    337     client->m_lease->bindingPhase(false);
    338 
    339     client->m_lease->setExpiration(client->m_lease->getConfig()->expirationPeriod());
    340     client->m_lease->phaseStart(RTTimeMilliTS());
     370    return Lease::NullLease;
     371}
     372
     373
     374int ConfigurationManager::commitLease4Client(Client& client)
     375{
     376    Lease l = client.lease();
     377    AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR);
     378
     379    l.bindingPhase(false);
     380    const NetworkConfigEntity *pCfg = l.getConfig();
     381
     382    AssertPtr(pCfg);
     383    l.setExpiration(pCfg->expirationPeriod());
     384    l.phaseStart(RTTimeMilliTS());
    341385
    342386    return VINF_SUCCESS;
    343387}
    344388
    345 int ConfigurationManager::expireLease4Client(Client *client)
    346 {
    347     MapLease2Ip4AddressIterator it = m_allocations.find(client->m_lease);
    348     AssertReturn(it != m_allocations.end(), VERR_NOT_FOUND);
    349 
    350     m_allocations.erase(it);
    351 
    352     delete client->m_lease;
    353     client->m_lease = NULL;
    354 
     389int ConfigurationManager::expireLease4Client(Client& client)
     390{
     391    Lease l = client.lease();
     392    AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR);
     393   
     394    if (l.isInBindingPhase())
     395    {
     396
     397        MapLease2Ip4AddressIterator it = m->m_allocations.find(l);
     398        AssertReturn(it != m->m_allocations.end(), VERR_NOT_FOUND);
     399
     400        /*
     401         * XXX: perhaps it better to keep this allocation ????
     402         */
     403        m->m_allocations.erase(it);
     404
     405        l.expire();
     406        return VINF_SUCCESS;
     407    }
     408   
     409    l = Lease(client); /* re-new */
    355410    return VINF_SUCCESS;
    356411}
    357412
    358 bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease)
     413bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease& lease)
    359414{
    360415    MapLease2Ip4AddressIterator it;
    361416
    362     for (it = m_allocations.begin();
    363          it != m_allocations.end();
     417    for (it = m->m_allocations.begin();
     418         it != m->m_allocations.end();
    364419         ++it)
    365420    {
    366421        if (it->second.u == addr.u)
    367422        {
    368             if (ppLease)
    369                 *ppLease = it->first;
     423            if (lease != Lease::NullLease)
     424                lease = it->first;
    370425
    371426            return true;
    372427        }
    373428    }
     429    lease = Lease::NullLease;
    374430    return false;
    375431}
     432
    376433
    377434NetworkConfigEntity *ConfigurationManager::addNetwork(NetworkConfigEntity *,
     
    424481    {
    425482        case RTNET_DHCP_OPT_DNS:
    426             m_nameservers.push_back(address);
     483            m->m_nameservers.push_back(address);
    427484            break;
    428485        case RTNET_DHCP_OPT_ROUTERS:
    429             m_routers.push_back(address);
     486            m->m_routers.push_back(address);
    430487            break;
    431488        default:
     
    435492}
    436493
     494
    437495int ConfigurationManager::flushAddressList(uint8_t u8OptId)
    438496{
     
    440498    {
    441499        case RTNET_DHCP_OPT_DNS:
    442             m_nameservers.clear();
     500            m->m_nameservers.clear();
    443501            break;
    444502        case RTNET_DHCP_OPT_ROUTERS:
    445             m_routers.clear();
     503            m->m_routers.clear();
    446504            break;
    447505        default:
     
    451509}
    452510
     511
    453512const Ipv4AddressContainer& ConfigurationManager::getAddressList(uint8_t u8OptId)
    454513{
     
    456515    {
    457516        case RTNET_DHCP_OPT_DNS:
    458             return m_nameservers;
     517            return m->m_nameservers;
    459518
    460519        case RTNET_DHCP_OPT_ROUTERS:
    461             return m_routers;
     520            return m->m_routers;
    462521
    463522    }
     
    466525}
    467526
     527
    468528int ConfigurationManager::setString(uint8_t u8OptId, const std::string& str)
    469529{
     
    471531    {
    472532        case RTNET_DHCP_OPT_DOMAIN_NAME:
    473             m_domainName = str;
     533            m->m_domainName = str;
    474534            break;
    475535        default:
     
    480540}
    481541
     542
    482543const std::string& ConfigurationManager::getString(uint8_t u8OptId)
    483544{
     
    485546    {
    486547        case RTNET_DHCP_OPT_DOMAIN_NAME:
    487             if (m_domainName.length())
    488                 return m_domainName;
     548            if (m->m_domainName.length())
     549                return m->m_domainName;
    489550            else
    490551                return m_noString;
     
    496557}
    497558
     559
     560void ConfigurationManager::init()
     561{
     562    m = new ConfigurationManager::Data();
     563}
     564
     565
     566ConfigurationManager::~ConfigurationManager() { if (m) delete m; }
     567
    498568/**
    499569 * Network manager
     
    511581 * Network manager creates DHCPOFFER datagramm
    512582 */
    513 int NetworkManager::offer4Client(Client *client, uint32_t u32Xid,
     583int NetworkManager::offer4Client(const Client& client, uint32_t u32Xid,
    514584                                 uint8_t *pu8ReqList, int cReqList)
    515585{
    516     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    517     AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
    518 
     586    Lease l(client); /* XXX: oh, it looks badly, but now we have lease */
    519587    prepareReplyPacket4Client(client, u32Xid);
    520588
    521 
    522     RTNETADDRIPV4 address = client->m_lease->getAddress();
     589    RTNETADDRIPV4 address = l.getAddress();
    523590    BootPReplyMsg.BootPHeader.bp_yiaddr =  address;
    524591
     
    534601    RT_ZERO(opt);
    535602
    536     /* XXX: can't store options per session */
    537     AssertPtr(client);
    538 
     603    std::vector<RawOption> extra(2);
    539604    opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
    540605    opt.au8RawOpt[0] = RTNET_DHCP_MT_OFFER;
    541606    opt.cbRawOpt = 1;
    542     client->rawOptions.push_back(opt);
     607    extra.push_back(opt);
    543608
    544609    opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME;
    545     *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->getConfig()->expirationPeriod());
     610
     611    const NetworkConfigEntity *pCfg = l.getConfig();
     612    AssertPtr(pCfg);
     613
     614    *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(pCfg->expirationPeriod());
    546615    opt.cbRawOpt = sizeof(RTNETADDRIPV4);
    547     client->rawOptions.push_back(opt);
     616
     617    extra.push_back(opt);
    548618
    549619    processParameterReqList(client, pu8ReqList, cReqList);
    550620
    551     return doReply(client);
     621    return doReply(client, extra);
    552622}
    553623
     
    556626 * Network manager creates DHCPACK
    557627 */
    558 int NetworkManager::ack(Client *client, uint32_t u32Xid,
     628int NetworkManager::ack(const Client& client, uint32_t u32Xid,
    559629                        uint8_t *pu8ReqList, int cReqList)
    560630{
    561     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    562     AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
    563 
    564631    RTNETADDRIPV4 address;
    565632
    566633    prepareReplyPacket4Client(client, u32Xid);
    567 
    568     address = client->m_lease->getAddress();
     634   
     635    Lease l = client.lease();
     636    address = l.getAddress();
    569637    BootPReplyMsg.BootPHeader.bp_ciaddr =  address;
    570638
     
    587655    RT_ZERO(opt);
    588656
     657    std::vector<RawOption> extra(2);
    589658    opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
    590659    opt.au8RawOpt[0] = RTNET_DHCP_MT_ACK;
    591660    opt.cbRawOpt = 1;
    592     client->rawOptions.push_back(opt);
     661    extra.push_back(opt);
    593662
    594663    /*
     
    597666     */
    598667    opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME;
    599     *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->getExpiration());
     668    *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(l.getExpiration());
    600669    opt.cbRawOpt = sizeof(RTNETADDRIPV4);
    601     client->rawOptions.push_back(opt);
     670    extra.push_back(opt);
    602671
    603672    processParameterReqList(client, pu8ReqList, cReqList);
    604673
    605     return doReply(client);
     674    return doReply(client, extra);
    606675}
    607676
     
    610679 * Network manager creates DHCPNAK
    611680 */
    612 int NetworkManager::nak(Client* client, uint32_t u32Xid)
    613 {
    614     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    615 
    616     if (!client->m_lease)
     681int NetworkManager::nak(const Client& client, uint32_t u32Xid)
     682{
     683
     684    Lease l = client.lease();
     685    if (l == Lease::NullLease)
    617686        return VERR_INTERNAL_ERROR;
    618687
     
    629698     */
    630699    RawOption opt;
    631     RT_ZERO(opt);
     700    std::vector<RawOption> extra;
    632701
    633702    opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
    634703    opt.au8RawOpt[0] = RTNET_DHCP_MT_NAC;
    635704    opt.cbRawOpt = 1;
    636     client->rawOptions.push_back(opt);
    637 
    638     return doReply(client);
     705    extra.push_back(opt);
     706
     707    return doReply(client, extra);
    639708}
    640709
     
    643712 *
    644713 */
    645 int NetworkManager::prepareReplyPacket4Client(Client *client, uint32_t u32Xid)
    646 {
    647     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    648     AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
    649 
     714int NetworkManager::prepareReplyPacket4Client(const Client& client, uint32_t u32Xid)
     715{
    650716    memset(&BootPReplyMsg, 0, sizeof(BootPReplyMsg));
    651717
     
    661727    BootPReplyMsg.BootPHeader.bp_giaddr.u = 0;
    662728
    663     BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client->m_mac;
    664 
    665     BootPReplyMsg.BootPHeader.bp_yiaddr = client->m_lease->getAddress();
     729    BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client.getMacAddress();
     730
     731    const Lease l = client.lease();
     732    BootPReplyMsg.BootPHeader.bp_yiaddr = l.getAddress();
    666733    BootPReplyMsg.BootPHeader.bp_siaddr.u = 0;
    667734
     
    677744
    678745
    679 int NetworkManager::doReply(Client *client)
     746int NetworkManager::doReply(const Client& client, const std::vector<RawOption>& extra)
    680747{
    681748    int rc;
    682 
    683     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    684     AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
    685749
    686750    /*
     
    693757    Cursor.optIPv4Addr(RTNET_DHCP_OPT_SERVER_ID, m_OurAddress);
    694758
    695     while(!client->rawOptions.empty())
    696     {
    697         RawOption opt = client->rawOptions.back();
    698         if (!Cursor.begin(opt.u8OptId, opt.cbRawOpt))
     759    const Lease l = client.lease();
     760    const std::map<uint8_t, RawOption>& options = l.options();
     761
     762    for(std::vector<RawOption>::const_iterator it = extra.begin();
     763        it != extra.end(); ++it)
     764    {
     765        if (!Cursor.begin(it->u8OptId, it->cbRawOpt))
    699766            break;
    700         Cursor.put(opt.au8RawOpt, opt.cbRawOpt);
    701 
    702         client->rawOptions.pop_back();
    703     }
    704 
    705 
    706     if (!client->rawOptions.empty())
    707     {
    708         Log(("Wasn't able to put all options\n"));
    709         /* force clean up */
    710         client->rawOptions.clear();
     767        Cursor.put(it->au8RawOpt, it->cbRawOpt);
     768
     769    }
     770
     771    for(std::map<uint8_t, RawOption>::const_iterator it = options.begin();
     772        it != options.end(); ++it)
     773    {
     774        if (!Cursor.begin(it->second.u8OptId, it->second.cbRawOpt))
     775            break;
     776        Cursor.put(it->second.au8RawOpt, it->second.cbRawOpt);
     777
    711778    }
    712779
     
    716783     */
    717784#if 0
    718     if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) /** @todo need to see someone set this flag to check that it's correct. */
     785    /** @todo need to see someone set this flag to check that it's correct. */
     786    if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) 
    719787    {
    720788        rc = VBoxNetUDPUnicast(m_pSession,
     
    746814
    747815
    748 int NetworkManager::processParameterReqList(Client* client, uint8_t *pu8ReqList, int cReqList)
     816int NetworkManager::processParameterReqList(const Client& client, uint8_t *pu8ReqList, int cReqList)
    749817{
    750818    /* request parameter list */
     
    752820    int idxParam = 0;
    753821
    754     AssertPtrReturn(client, VERR_INTERNAL_ERROR);
    755 
    756822    uint8_t *pReqList = pu8ReqList;
    757 
    758     const NetworkConfigEntity *pNetCfg = client->m_lease->getConfig();
     823   
     824    const Lease const_l = client.lease();
     825    Lease l = Lease(const_l);
     826   
     827    const NetworkConfigEntity *pNetCfg = l.getConfig();
    759828
    760829    for (idxParam = 0; idxParam < cReqList; ++idxParam)
    761830    {
    762831
     832        bool fIgnore = false;
    763833        RT_ZERO(opt);
    764834        opt.u8OptId = pReqList[idxParam];
     835
    765836        switch(pReqList[idxParam])
    766837        {
     
    768839                ((PRTNETADDRIPV4)opt.au8RawOpt)->u = pNetCfg->netmask().u;
    769840                opt.cbRawOpt = sizeof(RTNETADDRIPV4);
    770                 client->rawOptions.push_back(opt);
     841
    771842                break;
    772843
     
    787858                    }
    788859
    789                     if (!lst.empty())
    790                         client->rawOptions.push_back(opt);
     860                    if (lst.empty())
     861                        fIgnore = true;
    791862                }
    792863                break;
     
    795866                    std::string domainName = g_ConfigurationManager->getString(pReqList[idxParam]);
    796867                    if (domainName == g_ConfigurationManager->m_noString)
     868                    {
     869                        fIgnore = true;
    797870                        break;
     871                    }
    798872
    799873                    char *pszDomainName = (char *)&opt.au8RawOpt[0];
     
    801875                    strcpy(pszDomainName, domainName.c_str());
    802876                    opt.cbRawOpt = domainName.length();
    803                     client->rawOptions.push_back(opt);
    804877                }
    805878                break;
    806879            default:
    807880                Log(("opt: %d is ignored\n", pReqList[idxParam]));
     881                fIgnore = true;
    808882                break;
    809883        }
     884
     885        if (!fIgnore)
     886            l.options().insert(std::map<uint8_t, RawOption>::value_type(opt.u8OptId, opt));
     887
    810888    }
    811889
     
    813891}
    814892
    815 
    816 Lease::~Lease()
    817 {
    818     if (m)
    819         delete m;
    820 }
    821 
    822 
    823 void Lease::init()
    824 {
    825     if (!m)
    826         m = new Lease::Data();
     893/* Utility */
     894bool operator== (const RTMAC& lhs, const RTMAC& rhs)
     895{
     896    return (   lhs.au16[0] == rhs.au16[0]
     897            && lhs.au16[1] == rhs.au16[1]
     898            && lhs.au16[2] == rhs.au16[2]);
     899}
     900
     901
     902/* Client */
     903Client::Client()
     904{
     905    m = SharedPtr<ClientData>();
     906}
     907
     908
     909void Client::initWithMac(const RTMAC& mac)
     910{
     911    m = SharedPtr<ClientData>(new ClientData());
     912    m->m_mac = mac;
     913}
     914
     915
     916bool Client::operator== (const RTMAC& mac) const
     917{
     918    return (m.get() && m->m_mac == mac);
     919}
     920
     921
     922const RTMAC& Client::getMacAddress() const
     923{
     924    return m->m_mac;
     925}
     926
     927
     928Lease Client::lease()
     929{
     930    if (!m.get()) return Lease::NullLease;
     931
     932    if (m->fHasLease)
     933        return Lease(*this);
     934    else
     935        return Lease::NullLease;
     936}
     937
     938
     939const Lease Client::lease() const
     940{
     941    return const_cast<Client *>(this)->lease();
     942}
     943
     944
     945Client::Client(ClientData *data):m(SharedPtr<ClientData>(data)){}
     946
     947/* Lease */
     948Lease::Lease()
     949{
     950    m = SharedPtr<ClientData>();
     951}
     952
     953
     954Lease::Lease (const Client& c)
     955{
     956    m = SharedPtr<ClientData>(c.m);
     957    if (   !m->fHasLease
     958        || (   isExpired()
     959            && !isInBindingPhase()))
     960    {
     961        m->fHasLease = true;
     962        m->fBinding = true;
     963        phaseStart(RTTimeMilliTS());
     964    }
    827965}
    828966
     
    830968bool Lease::isExpired() const
    831969{
    832     AssertPtrReturn(m, false);
     970    AssertPtrReturn(m.get(), false);
    833971
    834972    if (!m->fBinding)
     
    841979
    842980
     981void Lease::expire()
     982{
     983    /* XXX: TODO */
     984}
     985
     986
    843987void Lease::phaseStart(uint64_t u64Start)
    844988{
     
    8621006
    8631007
     1008uint64_t Lease::issued() const
     1009{
     1010    return m->u64TimestampLeasingStarted;
     1011}
     1012
     1013
    8641014void Lease::setExpiration(uint32_t exp)
    8651015{
     
    9041054
    9051055
    906 Client *Lease::getClient() const
    907 {
    908     return m->m_client;
    909 }
    910 
    911 void Lease::setClient(Client *client)
    912 {
    913     m->m_client = client;
    914 }
     1056const MapOptionId2RawOption& Lease::options() const
     1057{
     1058    return m->options;
     1059}
     1060
     1061
     1062MapOptionId2RawOption& Lease::options()
     1063{
     1064    return m->options;
     1065}
     1066
     1067
     1068Lease::Lease(ClientData *pd):m(SharedPtr<ClientData>(pd)){}
     1069
     1070
     1071const Lease Lease::NullLease;
     1072
     1073
     1074const Client Client::NullClient;
  • trunk/src/VBox/NetworkServices/DHCP/Config.h

    r49063 r49327  
    1010#include <iprt/cpp/utils.h>
    1111
    12 typedef std::vector<RTMAC> MacAddressContainer;
    13 typedef MacAddressContainer::iterator MacAddressIterator;
    14 
    15 typedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer;
    16 typedef Ipv4AddressContainer::iterator Ipv4AddressIterator;
    17 typedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator;
    1812
    1913static bool operator <(const RTNETADDRIPV4& a, const RTNETADDRIPV4& b)
     
    3125{
    3226public:
     27    RawOption()
     28    {
     29        RT_ZERO(*this);
     30    }
    3331    uint8_t u8OptId;
    3432    uint8_t cbRawOpt;
     
    3634};
    3735
    38 
     36class ClientData;
    3937class Client;
    4038class Lease;
    4139class BaseConfigEntity;
    4240
    43 
    4441class NetworkConfigEntity;
    4542class HostConfigEntity;
    4643class ClientMatchCriteria;
    47 
    48 typedef std::map<Lease *, RTNETADDRIPV4> MapLease2Ip4Address;
    49 typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator;
    50 typedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair;
     44class ConfigurationManager;
    5145
    5246/*
     
    6155class Client
    6256{
     57    friend class Lease;
     58    friend class ConfigurationManager;
     59
    6360    public:
    64 
    65     /* XXX: Option 60 and 61 */
    66     Client(const RTMAC& mac);
    67 
    68     bool operator== (const RTMAC& mac) const
    69     {
    70         return (  m_mac.au16[0] == mac.au16[0]
    71                 && m_mac.au16[1] == mac.au16[1]
    72                 && m_mac.au16[2] == mac.au16[2]);
    73     }
     61    Client();
     62    void initWithMac(const RTMAC& mac);
     63    bool operator== (const RTMAC& mac) const;
     64    const RTMAC& getMacAddress() const;
     65
    7466    /** Dumps client query */
    7567    void dump();
    7668
    77     /* XXX! private: */
    78 
    79     RTMAC m_mac;
    80     Lease *m_lease;
    81 
    82     /* XXX: should be in lease */
    83     std::vector<RawOption> rawOptions;
    84 };
    85 
    86 
    87 typedef std::vector<Client*> VecClient;
     69    Lease lease();
     70    const Lease lease() const;
     71
     72    public:
     73    static const Client NullClient;
     74
     75    private:
     76    Client(ClientData *);
     77    SharedPtr<ClientData> m;
     78};
     79
     80
     81bool operator== (const Lease&, const Lease&);
     82bool operator!= (const Lease&, const Lease&);
     83bool operator< (const Lease&, const Lease&);
     84
     85
     86typedef std::map<uint8_t, RawOption> MapOptionId2RawOption;
     87typedef MapOptionId2RawOption::iterator MapOptionId2RawOptionIterator;
     88typedef MapOptionId2RawOption::const_iterator MapOptionId2RawOptionConstIterator;
     89typedef MapOptionId2RawOption::value_type MapOptionId2RawOptionValue;
     90
     91namespace xml {
     92    class ElementNode;
     93}
     94
     95class Lease
     96{
     97    friend class Client;
     98    friend bool operator== (const Lease&, const Lease&);
     99    //friend int ConfigurationManager::loadFromFile(const std::string&);
     100    friend class ConfigurationManager;
     101
     102    public:
     103    Lease();
     104    Lease(const Client&);
     105
     106    bool isExpired() const;
     107    void expire();
     108
     109    /* Depending on phase *Expiration and phaseStart initialize different values. */
     110    void bindingPhase(bool);
     111    void phaseStart(uint64_t u64Start);
     112    bool isInBindingPhase() const;
     113    /* returns 0 if in binding state */
     114    uint64_t issued() const;
     115
     116    void setExpiration(uint32_t);
     117    uint32_t getExpiration() const;
     118
     119    RTNETADDRIPV4 getAddress() const;
     120    void setAddress(RTNETADDRIPV4);
     121
     122    const NetworkConfigEntity *getConfig() const;
     123    void setConfig(NetworkConfigEntity *);
     124
     125    const MapOptionId2RawOption& options() const;
     126    MapOptionId2RawOption& options();
     127
     128
     129    public:
     130    static const Lease NullLease;
     131
     132    private:
     133    Lease(ClientData *);
     134    SharedPtr<ClientData> m;
     135};
     136
     137
     138typedef std::vector<Client> VecClient;
    88139typedef VecClient::iterator VecClientIterator;
    89140typedef VecClient::const_iterator VecClientConstIterator;
     141
     142typedef std::vector<RTMAC> MacAddressContainer;
     143typedef MacAddressContainer::iterator MacAddressIterator;
     144
     145typedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer;
     146typedef Ipv4AddressContainer::iterator Ipv4AddressIterator;
     147typedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator;
     148
     149typedef std::map<Lease, RTNETADDRIPV4> MapLease2Ip4Address;
     150typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator;
     151typedef MapLease2Ip4Address::const_iterator MapLease2Ip4AddressConstIterator;
     152typedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair;
    90153
    91154
     
    130193        return (m_left->check(client) && m_right->check(client));
    131194    }
     195
    132196private:
    133197    ClientMatchCriteria* m_left;
     
    156220        return (client == m_mac);
    157221    }
     222
    158223private:
    159224    RTMAC m_mac;
     
    185250class BaseConfigEntity
    186251{
    187 public:
     252    public:
    188253    BaseConfigEntity(const ClientMatchCriteria *criteria = NULL,
    189254      int matchingLevel = 0)
     
    202267    virtual uint32_t expirationPeriod() const = 0;
    203268
    204 protected:
     269    protected:
    205270    const ClientMatchCriteria *m_criteria;
    206271    int m_MatchLevel;
     
    211276class NullConfigEntity: public BaseConfigEntity
    212277{
    213 public:
     278    public:
    214279    NullConfigEntity(){}
    215280    virtual ~NullConfigEntity(){}
    216     int add(BaseConfigEntity *) const
    217     {
    218         return 0;
    219     }
     281    int add(BaseConfigEntity *) const { return 0;}
    220282    virtual uint32_t expirationPeriod() const {return 0;}
    221283};
     
    224286class ConfigEntity: public BaseConfigEntity
    225287{
    226 public:
     288    public:
    227289    /* range */
    228290    /* match conditions */
     
    320382        /* upper addr == lower addr */
    321383    }
    322 
    323     virtual int match(const Client& client) const
    324     {
    325         return (m_criteria->check(client) ? 10 : 0);
    326     }
    327 
    328384};
    329385
     
    368424     *
    369425     */
    370     Client* getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg);
     426    Client getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg);
    371427
    372428    /**
     
    375431     * allocation)...
    376432     */
    377     Lease* allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg);
     433    Lease allocateLease4Client(const Client& client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg);
    378434
    379435    /**
     
    381437     * when requested configuration is acceptable.
    382438     */
    383     int commitLease4Client(Client *client);
     439    int commitLease4Client(Client& client);
    384440
    385441    /**
    386442     * Expires client lease.
    387443     */
    388     int expireLease4Client(Client *client);
     444    int expireLease4Client(Client& client);
    389445
    390446    static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt);
     
    404460
    405461private:
    406     ConfigurationManager(){}
    407     virtual ~ConfigurationManager(){}
    408     bool isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease = NULL);
     462    ConfigurationManager():m(NULL){}
     463    void init();
     464
     465    ~ConfigurationManager();
     466    bool isAddressTaken(const RTNETADDRIPV4& addr, Lease& lease);
     467    bool isAddressTaken(const RTNETADDRIPV4& addr)
     468    {
     469        Lease ignore;
     470        return isAddressTaken(addr, ignore);
     471    }
    409472
    410473public:
     
    414477
    415478private:
    416     MapLease2Ip4Address m_allocations;
    417     /**
    418      * Here we can store expired Leases to do not re-allocate them latter.
    419      */
    420 
    421     /* XXX: MapLease2Ip4Address m_freed; */
    422     /* XXX: more universal storages are required. */
    423     Ipv4AddressContainer m_nameservers;
    424     Ipv4AddressContainer m_routers;
    425 
    426     std::string          m_domainName;
    427     VecClient m_clients;
     479    struct Data;
     480    Data *m;
    428481};
    429482
     
    434487    static NetworkManager *getNetworkManager();
    435488
    436     int offer4Client(Client* lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
    437     int ack(Client *lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
    438     int nak(Client *lease, uint32_t u32Xid);
     489    int offer4Client(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
     490    int ack(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
     491    int nak(const Client& lease, uint32_t u32Xid);
    439492
    440493    const RTNETADDRIPV4& getOurAddress(){ return m_OurAddress;}
     
    455508    virtual ~NetworkManager(){}
    456509
    457     int prepareReplyPacket4Client(Client *client, uint32_t u32Xid);
    458     int doReply(Client *client);
    459     int processParameterReqList(Client *client, uint8_t *pu8ReqList, int cReqList);
     510    int prepareReplyPacket4Client(const Client& client, uint32_t u32Xid);
     511    int doReply(const Client& client, const std::vector<RawOption>& extra);
     512    int processParameterReqList(const Client& client, uint8_t *pu8ReqList, int cReqList);
    460513
    461514    union {
     
    469522    RTMAC m_OurMac;
    470523};
    471 
    472 
    473 
    474 class Lease
    475 {
    476 public:
    477     Lease():m(NULL){};
    478     ~Lease();
    479     void init();
    480 
    481     bool isExpired() const;
    482 
    483     /* Depending on phase *Expiration and phaseStart initialize different values. */
    484     void bindingPhase(bool);
    485     void phaseStart(uint64_t u64Start);
    486     bool isInBindingPhase() const;
    487 
    488     void setExpiration(uint32_t);
    489     uint32_t getExpiration() const;
    490 
    491     RTNETADDRIPV4 getAddress() const;
    492     void setAddress(RTNETADDRIPV4);
    493 
    494     const NetworkConfigEntity *getConfig() const;
    495     void setConfig(NetworkConfigEntity *);
    496    
    497     Client *getClient() const;
    498     void setClient(Client *);
    499 
    500     private:
    501     class Data;
    502    
    503     Data *m;
    504 };
    505 
    506524
    507525
  • trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp

    r49113 r49327  
    5656
    5757#include "../NetLib/VBoxNetLib.h"
     58#include "../NetLib/shared_ptr.h"
    5859
    5960#include <vector>
     
    470471
    471472        }
     473       
    472474    }
    473475
     
    725727        /* 1. Find client */
    726728        ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    727         Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
     729        Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
    728730
    729731        /* 2. Find/Bind lease for client */
    730         Lease *lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);
    731         AssertPtrReturn(lease, VINF_SUCCESS);
     732        Lease lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);
     733        AssertReturn(lease != Lease::NullLease, VINF_SUCCESS);
    732734
    733735        int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);
     
    736738        NetworkManager *networkManager = NetworkManager::getNetworkManager();
    737739
    738         lease->bindingPhase(true);
    739         lease->phaseStart(RTTimeMilliTS());
    740         lease->setExpiration(300); /* 3 min. */
     740        lease.bindingPhase(true);
     741        lease.phaseStart(RTTimeMilliTS());
     742        lease.setExpiration(300); /* 3 min. */
    741743        networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
    742744    } /* end of if(!m_DhcpServer.isNull()) */
     
    760762
    761763    /* 1. find client */
    762     Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
     764    Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);
    763765
    764766    /* 2. find bound lease */
    765     if (client->m_lease)
    766     {
    767 
    768         if (client->m_lease->isExpired())
     767    Lease l = client.lease();
     768    if (l != Lease::NullLease)
     769    {
     770
     771        if (l.isExpired())
    769772        {
    770773            /* send client to INIT state */
     774            Client c(client);
    771775            networkManager->nak(client, pDhcpMsg->bp_xid);
    772             confManager->expireLease4Client(client);
     776            confManager->expireLease4Client(c);
    773777            return true;
    774778        }
    775         /* XXX: Validate request */
    776         RawOption opt;
    777         memset((void *)&opt, 0, sizeof(RawOption));
    778 
    779         int rc = confManager->commitLease4Client(client);
    780         AssertRCReturn(rc, false);
    781 
    782         rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);
    783         AssertRCReturn(rc, false);
    784 
    785         networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
     779        else {
     780            /* XXX: Validate request */
     781            RawOption opt;
     782            RT_ZERO(opt);
     783
     784            Client c(client);
     785            int rc = confManager->commitLease4Client(c);
     786            AssertRCReturn(rc, false);
     787
     788            rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);
     789            AssertRCReturn(rc, false);
     790
     791            networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
     792        }
    786793    }
    787794    else
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