VirtualBox

Ignore:
Timestamp:
Jul 6, 2019 1:22:56 AM (6 years ago)
Author:
vboxsync
Message:

Dhcpd: Went over the Dhcpd and related code adding comments and doing some exception vetting. bugref:9288

Location:
trunk/src/VBox/NetworkServices/Dhcpd
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/Dhcpd/ClientId.cpp

    r79524 r79563  
    3434 * Registers the ClientId format type callback ("%R[id]").
    3535 */
    36 void ClientId::registerFormat()
     36void ClientId::registerFormat() RT_NOEXCEPT
    3737{
    3838    if (!g_fFormatRegistered)
     
    8282
    8383
    84 bool operator==(const ClientId &l, const ClientId &r)
     84bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT
    8585{
    8686    if (l.m_id.present())
     
    9999
    100100
    101 bool operator<(const ClientId &l, const ClientId &r)
     101bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT
    102102{
    103103    if (l.m_id.present())
  • trunk/src/VBox/NetworkServices/Dhcpd/ClientId.h

    r79529 r79563  
    4141        : m_mac(), m_id()
    4242    {}
     43    /** @throws std::bad_alloc */
    4344    ClientId(const RTMAC &a_mac, const OptClientId &a_id)
    4445        : m_mac(a_mac), m_id(a_id)
    4546    {}
     47    /** @throws std::bad_alloc */
    4648    ClientId(const ClientId &a_rThat)
    4749        : m_mac(a_rThat.m_mac), m_id(a_rThat.m_id)
    4850    {}
     51    /** @throws std::bad_alloc */
    4952    ClientId &operator=(const ClientId &a_rThat)
    5053    {
     
    5457    }
    5558
    56     const RTMAC       &mac() const { return m_mac; }
    57     const OptClientId &id() const   { return m_id; }
     59    const RTMAC       &mac() const RT_NOEXCEPT { return m_mac; }
     60    const OptClientId &id() const RT_NOEXCEPT   { return m_id; }
    5861
    5962    /** @name String formatting of %R[id].
    6063     * @{ */
    61     static void registerFormat();
     64    static void registerFormat() RT_NOEXCEPT;
    6265private:
    6366    static DECLCALLBACK(size_t) rtStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType,
     
    6669    /** @} */
    6770
    68     friend bool operator==(const ClientId &l, const ClientId &r);
    69     friend bool operator<(const ClientId &l, const ClientId &r);
     71    friend bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
     72    friend bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
    7073};
    7174
    72 bool operator==(const ClientId &l, const ClientId &r);
    73 bool operator<(const ClientId &l, const ClientId &r);
     75bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
     76bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
    7477
    75 inline bool operator!=(const ClientId &l, const ClientId &r)
     78inline bool operator!=(const ClientId &l, const ClientId &r) RT_NOEXCEPT
    7679{
    7780    return !(l == r);
  • trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp

    r79553 r79563  
    8888 * @returns IPRT status code.
    8989 */
    90 int Config::i_init()
     90int Config::i_init() RT_NOEXCEPT
    9191{
    9292    return i_homeInit();
     
    100100 * @todo Too many init functions?
    101101 */
    102 int Config::i_homeInit()
     102int Config::i_homeInit() RT_NOEXCEPT
    103103{
    104104    char szHome[RTPATH_MAX];
     
    121121 * @returns Config instance on success, NULL on failure.
    122122 */
    123 /*static*/ Config *Config::i_createInstanceAndCallInit()
     123/*static*/ Config *Config::i_createInstanceAndCallInit() RT_NOEXCEPT
    124124{
    125125    Config *pConfig;
     
    161161 * Interal worker for i_setNetwork() that sets m_strBaseName to sanitized the
    162162 * version of m_strNetwork suitable for use as a path component.
     163 *
     164 * @throws std::bad_alloc
    163165 */
    164166void Config::i_sanitizeBaseName()
     
    196198 * @todo make the log file directly configurable?
    197199 */
    198 int Config::i_logInit()
     200int Config::i_logInit() RT_NOEXCEPT
    199201{
    200202    if (m_strHome.isEmpty() || m_strBaseName.isEmpty())
     
    241243 * Post process and validate the configuration after it has been loaded.
    242244 */
    243 int Config::i_complete()
     245int Config::i_complete() RT_NOEXCEPT
    244246{
    245247    if (m_strNetwork.isEmpty())
     
    336338
    337339
    338 /*static*/ Config *Config::hardcoded()
     340/*static*/ Config *Config::hardcoded() RT_NOEXCEPT
    339341{
    340342    std::unique_ptr<Config> config(i_createInstanceAndCallInit());
     
    378380
    379381
    380 
     382/**
     383 * Old VBoxNetDHCP style command line parsing.
     384 *
     385 * @throws std::bad_alloc
     386 */
    381387/*static*/ Config *Config::compat(int argc, char **argv)
    382388{
     
    519525
    520526
    521 Config *Config::create(int argc, char **argv)
    522 {
    523 #define DHCPD_GETOPT_COMMENT 256 /* No short option for --comment */
     527Config *Config::create(int argc, char **argv) RT_NOEXCEPT
     528{
    524529    static const RTGETOPTDEF s_aOptions[] =
    525530    {
    526         { "--config",       'c',                  RTGETOPT_REQ_STRING },
    527         { "--comment",      DHCPD_GETOPT_COMMENT, RTGETOPT_REQ_STRING }
     531        { "--config",       'c', RTGETOPT_REQ_STRING },
     532        { "--comment",      '#', RTGETOPT_REQ_STRING }
    528533    };
    529534
     
    556561                break;
    557562
    558             case DHCPD_GETOPT_COMMENT: /* --comment */
     563            case '#': /* --comment */
    559564                /* The sole purpose of this option is to allow identification of DHCP
    560565                 * server instances in the process list. We ignore the required string
     
    589594 * @note The release log has is not operational when this method is called.
    590595 */
    591 Config *Config::i_read(const char *pszFileName)
     596Config *Config::i_read(const char *pszFileName) RT_NOEXCEPT
    592597{
    593598    if (pszFileName == NULL || pszFileName[0] == '\0')
     
    635640        return NULL;
    636641    }
     642    catch (std::bad_alloc &)
     643    {
     644        LogFunc(("std::bad_alloc\n"));
     645        RTMsgError("std::bad_alloc reading config\n");
     646        return NULL;
     647    }
    637648    catch (...)
    638649    {
     
    650661 * below it.
    651662 *
    652  * @throws stuff.
     663 * @param   pElmRoot    The root element.
     664 * @throws  std::bad_alloc, ConfigFileError
    653665 */
    654666void Config::i_parseConfig(const xml::ElementNode *pElmRoot)
     
    694706 *
    695707 * @param   pElmServer          The DHCPServer element.
    696  * @throws  ConfigFileError
     708 * @throws  std::bad_alloc, ConfigFileError
    697709 */
    698710void Config::i_parseServer(const xml::ElementNode *pElmServer)
     
    767779 *
    768780 * @param   pElmServer          The <Options> element.
    769  * @throws  ConfigFileError
     781 * @throws  std::bad_alloc, ConfigFileError
    770782 */
    771783void Config::i_parseGlobalOptions(const xml::ElementNode *options)
     
    792804 *
    793805 * @param   pElmServer          The <Config> element.
    794  * @throws  ConfigFileError
     806 * @throws  std::bad_alloc, ConfigFileError
    795807 */
    796808void Config::i_parseVMConfig(const xml::ElementNode *pElmConfig)
     
    841853 * @param   pElmServer          The <Option> element.
    842854 * @param   optmap              The option map to add the option to.
    843  * @throws  ConfigFileError
     855 * @throws  std::bad_alloc, ConfigFileError
    844856 */
    845857void Config::i_parseOption(const xml::ElementNode *pElmOption, optmap_t &optmap)
     
    946958 * @param   idVendorClass   The vendor class ID.
    947959 * @param   idUserClass     The user class ID.
     960 *
     961 * @throws  std::bad_alloc
    948962 */
    949963optmap_t &Config::getOptions(optmap_t &a_rRetOpts, const OptParameterRequest &reqOpts, const ClientId &id,
  • trunk/src/VBox/NetworkServices/Dhcpd/Config.h

    r79553 r79563  
    7272    Config();
    7373
    74     int                 i_init();
    75     int                 i_homeInit();
    76     static Config      *i_createInstanceAndCallInit();
    77     int                 i_logInit();
    78     int                 i_complete();
     74    int                 i_init() RT_NOEXCEPT;
     75    int                 i_homeInit() RT_NOEXCEPT;
     76    static Config      *i_createInstanceAndCallInit() RT_NOEXCEPT;
     77    int                 i_logInit() RT_NOEXCEPT;
     78    int                 i_complete() RT_NOEXCEPT;
    7979
    8080public:
    8181    /** @name Factory methods
    8282     * @{ */
    83     static Config      *hardcoded();                   /**< For testing. */
    84     static Config      *create(int argc, char **argv); /**< --config */
    85     static Config      *compat(int argc, char **argv); /**< Old VBoxNetDHCP command line parsing. */
     83    static Config      *hardcoded() RT_NOEXCEPT;                    /**< For testing. */
     84    static Config      *create(int argc, char **argv) RT_NOEXCEPT; /**< --config */
     85    static Config      *compat(int argc, char **argv);
    8686    /** @} */
    8787
    8888    /** @name Accessors
    8989     * @{ */
    90     const RTCString    &getHome() const             { return m_strHome; }
     90    const RTCString    &getHome() const RT_NOEXCEPT             { return m_strHome; }
    9191
    92     const RTCString    &getNetwork() const          { return m_strNetwork; }
     92    const RTCString    &getNetwork() const RT_NOEXCEPT          { return m_strNetwork; }
    9393
    94     const RTCString    &getBaseName() const         { return m_strBaseName; }
    95     const RTCString    &getTrunk() const            { return m_strTrunk; }
    96     INTNETTRUNKTYPE     getTrunkType() const        { return m_enmTrunkType; }
     94    const RTCString    &getBaseName() const RT_NOEXCEPT         { return m_strBaseName; }
     95    const RTCString    &getTrunk() const RT_NOEXCEPT            { return m_strTrunk; }
     96    INTNETTRUNKTYPE     getTrunkType() const RT_NOEXCEPT        { return m_enmTrunkType; }
    9797
    98     const RTMAC        &getMacAddress() const       { return m_MacAddress; }
     98    const RTMAC        &getMacAddress() const RT_NOEXCEPT       { return m_MacAddress; }
    9999
    100     RTNETADDRIPV4       getIPv4Address() const      { return m_IPv4Address; }
    101     RTNETADDRIPV4       getIPv4Netmask() const      { return m_IPv4Netmask; }
     100    RTNETADDRIPV4       getIPv4Address() const RT_NOEXCEPT      { return m_IPv4Address; }
     101    RTNETADDRIPV4       getIPv4Netmask() const RT_NOEXCEPT      { return m_IPv4Netmask; }
    102102
    103     RTNETADDRIPV4       getIPv4PoolFirst() const    { return m_IPv4PoolFirst; }
    104     RTNETADDRIPV4       getIPv4PoolLast() const     { return m_IPv4PoolLast; }
     103    RTNETADDRIPV4       getIPv4PoolFirst() const RT_NOEXCEPT    { return m_IPv4PoolFirst; }
     104    RTNETADDRIPV4       getIPv4PoolLast() const RT_NOEXCEPT     { return m_IPv4PoolLast; }
    105105    /** @} */
    106106
     
    112112    /** @name Configuration file reading and parsing
    113113     * @{ */
    114     static Config      *i_read(const char *pszFileName);
     114    static Config      *i_read(const char *pszFileName) RT_NOEXCEPT;
    115115    void                i_parseConfig(const xml::ElementNode *root);
    116116    void                i_parseServer(const xml::ElementNode *server);
  • trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.cpp

    r79553 r79563  
    1616 */
    1717
     18
     19/*********************************************************************************************************************************
     20*   Header Files                                                                                                                 *
     21*********************************************************************************************************************************/
    1822#include "DhcpdInternal.h"
    1923#include "DHCPD.h"
    2024#include "DhcpOptions.h"
    2125
    22 #include <iprt/path.h>
     26#include <iprt/message.h>
     27#include <iprt/cpp/path.h>
    2328
    2429
     
    2934
    3035
    31 int DHCPD::init(const Config *pConfig)
    32 {
    33     int rc;
    34 
    35     if (m_pConfig != NULL)
    36         return VERR_INVALID_STATE;
     36/**
     37 * Initializes the DHCPD with the given config.
     38 *
     39 * @returns VBox status code.
     40 * @param   pConfig     The configuration to use.
     41 */
     42int DHCPD::init(const Config *pConfig) RT_NOEXCEPT
     43{
     44    Assert(pConfig);
     45    AssertReturn(!m_pConfig, VERR_INVALID_STATE);
    3746
    3847    /** @todo r=bird: This must be configurable so main can read the database and
     
    4049     * figuring  out the IP address of a VM.) */
    4150
    42     /* leases file name */
    43     m_strLeasesFileName = pConfig->getHome();
    44     m_strLeasesFileName += RTPATH_DELIMITER;
    45     m_strLeasesFileName += pConfig->getBaseName();
    46     m_strLeasesFileName += "-Dhcpd.leases";
    47 
    48     rc = m_db.init(pConfig);
    49     if (RT_FAILURE(rc))
    50         return rc;
    51 
    52     loadLeases();
    53 
    54     m_pConfig = pConfig;
    55     return VINF_SUCCESS;
    56 }
    57 
    58 
    59 void DHCPD::loadLeases()
    60 {
    61     m_db.loadLeases(m_strLeasesFileName);
    62 }
    63 
    64 
    65 void DHCPD::saveLeases()
     51    /* leases filename */
     52    int rc = m_strLeasesFilename.assignNoThrow(pConfig->getHome());
     53    if (RT_SUCCESS(rc))
     54        rc = RTPathAppendCxx(m_strLeasesFilename, pConfig->getBaseName());
     55    if (RT_SUCCESS(rc))
     56        rc = m_strLeasesFilename.appendNoThrow("-Dhcpd.leases");
     57    if (RT_SUCCESS(rc))
     58    {
     59        /* Load the lease database, ignoring most issues except being out of memory: */
     60        rc = m_db.init(pConfig);
     61        if (RT_SUCCESS(rc))
     62        {
     63            rc = i_loadLeases();
     64            if (rc != VERR_NO_MEMORY)
     65            {
     66                m_pConfig = pConfig;
     67                rc = VINF_SUCCESS;
     68            }
     69            else
     70            {
     71                LogRel(("Ran out of memory loading leases from '%s'.  Try rename or delete the file.\n",
     72                        m_strLeasesFilename.c_str()));
     73                RTMsgError("Ran out of memory loading leases from '%s'.  Try rename or delete the file.\n",
     74                           m_strLeasesFilename.c_str());
     75            }
     76        }
     77    }
     78    return rc;
     79}
     80
     81
     82/**
     83 * Load leases from m_strLeasesFilename.
     84 */
     85int DHCPD::i_loadLeases() RT_NOEXCEPT
     86{
     87    return m_db.loadLeases(m_strLeasesFilename);
     88}
     89
     90
     91/**
     92 * Save the current leases to m_strLeasesFilename, doing expiry first.
     93 *
     94 * This is called after m_db is updated during a client request, so the on disk
     95 * database is always up-to-date.   This means it doesn't matter if we're
     96 * terminated with extreme prejudice, and it allows Main to look up IP addresses
     97 * for VMs.
     98 *
     99 * @throws nothing
     100 */
     101void DHCPD::i_saveLeases() RT_NOEXCEPT
    66102{
    67103    m_db.expire();
    68     m_db.writeLeases(m_strLeasesFileName);
    69 }
    70 
    71 
    72 DhcpServerMessage *DHCPD::process(DhcpClientMessage &req)
    73 {
    74     DhcpServerMessage *reply = NULL;
    75 
    76     req.dump();
    77 
     104    m_db.writeLeases(m_strLeasesFilename);
     105}
     106
     107
     108/**
     109 * Process a DHCP client message.
     110 *
     111 * Called by VBoxNetDhcpd::dhcp4Recv().
     112 *
     113 * @returns Pointer to DHCP reply (caller deletes this).  NULL if no reply
     114 *          warranted or we're out of memory.
     115 * @param   req                 The client message.
     116 * @throws  nothing
     117 */
     118DhcpServerMessage *DHCPD::process(DhcpClientMessage &req) RT_NOEXCEPT
     119{
     120    /*
     121     * Dump the package if release log level 3+1 are enable or if debug logging is
     122     * enabled.  We don't normally want to do this at the default log level, of course.
     123     */
     124    if ((LogRelIs3Enabled() && LogRelIsEnabled()) || LogIsEnabled())
     125        req.dump();
     126
     127    /*
     128     * Fend off requests that are not for us.
     129     */
    78130    OptServerId sid(req);
    79131    if (sid.present() && sid.value().u != m_pConfig->getIPv4Address().u)
    80132    {
    81133        if (req.broadcasted() && req.messageType() == RTNET_DHCP_MT_REQUEST)
     134        {
     135            LogRel2(("Message is not for us, canceling any pending offer.\n"));
    82136            m_db.cancelOffer(req);
    83 
    84         return NULL;
    85     }
     137        }
     138        else
     139            LogRel2(("Message is not for us.\n"));
     140        return NULL;
     141    }
     142
     143    /*
     144     * Process it.
     145     */
     146    DhcpServerMessage *reply = NULL;
    86147
    87148    switch (req.messageType())
     
    91152         */
    92153        case RTNET_DHCP_MT_DISCOVER:
    93             reply = doDiscover(req);
     154            try
     155            {
     156                reply = i_doDiscover(req);
     157            }
     158            catch (std::bad_alloc &)
     159            {
     160                LogRelFunc(("i_doDiscover threw bad_alloc\n"));
     161            }
    94162            break;
    95163
    96164        case RTNET_DHCP_MT_REQUEST:
    97             reply = doRequest(req);
     165            try
     166            {
     167                reply = i_doRequest(req);
     168            }
     169            catch (std::bad_alloc &)
     170            {
     171                LogRelFunc(("i_doRequest threw bad_alloc\n"));
     172            }
    98173            break;
    99174
    100175        case RTNET_DHCP_MT_INFORM:
    101             reply = doInform(req);
     176            try
     177            {
     178                reply = i_doInform(req);
     179            }
     180            catch (std::bad_alloc &)
     181            {
     182                LogRelFunc(("i_doInform threw bad_alloc\n"));
     183            }
    102184            break;
    103185
     
    106188         */
    107189        case RTNET_DHCP_MT_DECLINE:
    108             doDecline(req);
     190            i_doDecline(req);
    109191            break;
    110192
    111193        case RTNET_DHCP_MT_RELEASE:
    112             doRelease(req);
     194            i_doRelease(req);
    113195            break;
    114196
     
    116198         * Unexpected or unknown message types.
    117199         */
    118         case RTNET_DHCP_MT_OFFER: /* FALLTHROUGH */
    119         case RTNET_DHCP_MT_ACK:   /* FALLTHROUGH */
    120         case RTNET_DHCP_MT_NAC:   /* FALLTHROUGH */
     200        case RTNET_DHCP_MT_OFFER:
     201            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_OFFER!\n"));
     202            break;
     203        case RTNET_DHCP_MT_ACK:
     204            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_ACK!\n"));
     205            break;
     206        case RTNET_DHCP_MT_NAC:
     207            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_NAC!\n"));
     208            break;
    121209        default:
     210            LogRel2(("Ignoring unexpected message of unknown type: %d (%#x)!\n", req.messageType(), req.messageType()));
    122211            break;
    123212    }
     
    127216
    128217
    129 DhcpServerMessage *DHCPD::createMessage(int type, DhcpClientMessage &req)
     218/**
     219 * Internal helper.
     220 *
     221 * @throws  std::bad_alloc
     222 */
     223DhcpServerMessage *DHCPD::i_createMessage(int type, DhcpClientMessage &req)
    130224{
    131225    return new DhcpServerMessage(req, type, m_pConfig->getIPv4Address());
     
    133227
    134228
    135 DhcpServerMessage *DHCPD::doDiscover(DhcpClientMessage &req)
    136 {
    137     /*
     229/**
     230 * 4.3.1 DHCPDISCOVER message
     231 *
     232 * When a server receives a DHCPDISCOVER message from a client, the server
     233 * chooses a network address for the requesting client. If no address is
     234 * available, the server may choose to report the problem to the system
     235 * administrator. If an address is available, the new address SHOULD be chosen
     236 * as follows:
     237 *  - The client's current address as recorded in the client's current binding,
     238 *    ELSE
     239 *  - The client's previous address as recorded in the client's (now expired or
     240 *    released) binding, if that address is in the server's pool of available
     241 *    addresses and not already allocated, ELSE
     242 *  - The address requested in the 'Requested IP Address' option, if that
     243 *    address is valid and not already allocated, ELSE
     244 *  - A new address allocated from the server's pool of available addresses;
     245 *    the address is selected based on the subnet from which the message was
     246 *    received (if 'giaddr' is 0) or on the address of the relay agent that
     247 *    forwarded the message ('giaddr' when not 0).
     248 *
     249 * ...
     250 *
     251 * @throws  std::bad_alloc
     252 */
     253DhcpServerMessage *DHCPD::i_doDiscover(DhcpClientMessage &req)
     254{
     255    /** @todo
    138256     * XXX: TODO: Windows iSCSI initiator sends DHCPDISCOVER first and
    139257     * it has ciaddr filled.  Shouldn't let it screw up the normal
     
    148266        return NULL;
    149267
    150 
    151268    std::unique_ptr<DhcpServerMessage> reply;
    152269
     
    154271    if (!fRapidCommit)
    155272    {
    156         reply.reset(createMessage(RTNET_DHCP_MT_OFFER, req));
     273        reply.reset(i_createMessage(RTNET_DHCP_MT_OFFER, req));
    157274
    158275        if (b->state() < Binding::OFFERED)
    159276            b->setState(Binding::OFFERED);
    160277
    161         /* use small lease time internally to quickly free unclaimed offers? */
     278        /** @todo use small lease time internally to quickly free unclaimed offers? */
    162279    }
    163280    else
    164281    {
    165         reply.reset(createMessage(RTNET_DHCP_MT_ACK, req));
     282        reply.reset(i_createMessage(RTNET_DHCP_MT_ACK, req));
    166283        reply->addOption(OptRapidCommit(true));
    167284
    168285        b->setState(Binding::ACKED);
    169         saveLeases();
     286        i_saveLeases();
    170287    }
    171288
     
    178295    reply->addOptions(m_pConfig->getOptions(replyOptions, optlist, req.clientId()));
    179296
    180     // reply->maybeUnicast(req); /* XXX: we reject ciaddr != 0 above */
     297    // reply->maybeUnicast(req); /** @todo XXX: we reject ciaddr != 0 above */
    181298    return reply.release();
    182299}
    183300
    184301
    185 DhcpServerMessage *DHCPD::doRequest(DhcpClientMessage &req)
     302/**
     303 * 4.3.2 DHCPREQUEST message
     304 *
     305 * A DHCPREQUEST message may come from a client responding to a DHCPOFFER
     306 * message from a server, from a client verifying a previously allocated IP
     307 * address or from a client extending the lease on a network address. If the
     308 * DHCPREQUEST message contains a 'server identifier' option, the message is in
     309 * response to a DHCPOFFER message. Otherwise, the message is a request to
     310 * verify or extend an existing lease. If the client uses a 'client identifier'
     311 * in a DHCPREQUEST message, it MUST use that same 'client identifier' in all
     312 * subsequent messages. If the client included a list of requested parameters in
     313 * a DHCPDISCOVER message, it MUST include that list in all subsequent messages.
     314 *
     315 * ...
     316 *
     317 * @throws  std::bad_alloc
     318 */
     319DhcpServerMessage *DHCPD::i_doRequest(DhcpClientMessage &req)
    186320{
    187321    OptRequestedAddress reqAddr(req);
     
    189323    {
    190324        std::unique_ptr<DhcpServerMessage> nak (
    191             createMessage(RTNET_DHCP_MT_NAC, req)
     325            i_createMessage(RTNET_DHCP_MT_NAC, req)
    192326        );
    193327        nak->addOption(OptMessage("Requested address does not match ciaddr"));
     
    199333    if (b == NULL)
    200334    {
    201         return createMessage(RTNET_DHCP_MT_NAC, req);
    202     }
    203 
    204 
    205     std::unique_ptr<DhcpServerMessage> ack (
    206         createMessage(RTNET_DHCP_MT_ACK, req)
    207     );
     335        return i_createMessage(RTNET_DHCP_MT_NAC, req);
     336    }
     337
     338
     339    std::unique_ptr<DhcpServerMessage> ack(i_createMessage(RTNET_DHCP_MT_ACK, req));
    208340
    209341    b->setState(Binding::ACKED);
    210     saveLeases();
     342    i_saveLeases();
    211343
    212344    ack->setYiaddr(b->addr());
     
    224356
    225357
    226 /*
     358/**
    227359 * 4.3.5 DHCPINFORM message
    228360 *
    229  *    The server responds to a DHCPINFORM message by sending a DHCPACK
    230  *    message directly to the address given in the 'ciaddr' field of the
    231  *    DHCPINFORM message.  The server MUST NOT send a lease expiration time
    232  *    to the client and SHOULD NOT fill in 'yiaddr'.  The server includes
    233  *    other parameters in the DHCPACK message as defined in section 4.3.1.
    234  */
    235 DhcpServerMessage *DHCPD::doInform(DhcpClientMessage &req)
     361 * The server responds to a DHCPINFORM message by sending a DHCPACK message
     362 * directly to the address given in the 'ciaddr' field of the DHCPINFORM
     363 * message.  The server MUST NOT send a lease expiration time to the client and
     364 * SHOULD NOT fill in 'yiaddr'.  The server includes other parameters in the
     365 * DHCPACK message as defined in section 4.3.1.
     366 *
     367 * @throws  std::bad_alloc
     368 */
     369DhcpServerMessage *DHCPD::i_doInform(DhcpClientMessage &req)
    236370{
    237371    if (req.ciaddr().u == 0)
     
    247381        return NULL;
    248382
    249     std::unique_ptr<DhcpServerMessage> ack (
    250         createMessage(RTNET_DHCP_MT_ACK, req)
    251     );
    252 
     383    std::unique_ptr<DhcpServerMessage> ack(i_createMessage(RTNET_DHCP_MT_ACK, req));
    253384    ack->addOptions(info);
    254 
    255385    ack->maybeUnicast(req);
    256386    return ack.release();
     
    258388
    259389
    260 /*
     390/**
    261391 * 4.3.3 DHCPDECLINE message
    262392 *
    263  *    If the server receives a DHCPDECLINE message, the client has
    264  *    discovered through some other means that the suggested network
    265  *    address is already in use.  The server MUST mark the network address
    266  *    as not available and SHOULD notify the local system administrator of
    267  *    a possible configuration problem.
    268  */
    269 DhcpServerMessage *DHCPD::doDecline(DhcpClientMessage &req)
     393 * If the server receives a DHCPDECLINE message, the client has discovered
     394 * through some other means that the suggested network address is already in
     395 * use.  The server MUST mark the network address as not available and SHOULD
     396 * notify the local system administrator of a possible configuration problem.
     397 *
     398 * @throws  nothing
     399 */
     400DhcpServerMessage *DHCPD::i_doDecline(const DhcpClientMessage &req) RT_NOEXCEPT
    270401{
    271402    RT_NOREF(req);
     
    274405
    275406
    276 /*
     407/**
    277408 * 4.3.4 DHCPRELEASE message
    278409 *
    279  *    Upon receipt of a DHCPRELEASE message, the server marks the network
    280  *    address as not allocated.  The server SHOULD retain a record of the
    281  *    client's initialization parameters for possible reuse in response to
    282  *    subsequent requests from the client.
    283  */
    284 DhcpServerMessage *DHCPD::doRelease(DhcpClientMessage &req)
    285 {
    286     if (req.ciaddr().u == 0)
    287         return NULL;
    288 
    289     bool released = m_db.releaseBinding(req);
    290     if (released)
    291         saveLeases();
     410 * Upon receipt of a DHCPRELEASE message, the server marks the network address
     411 * as not allocated.  The server SHOULD retain a record of the client's
     412 * initialization parameters for possible reuse in response to subsequent
     413 * requests from the client.
     414 *
     415 * @throws  nothing
     416 */
     417DhcpServerMessage *DHCPD::i_doRelease(const DhcpClientMessage &req) RT_NOEXCEPT
     418{
     419    if (req.ciaddr().u != 0)
     420    {
     421        bool fReleased = m_db.releaseBinding(req);
     422        if (fReleased)
     423            i_saveLeases();
     424    }
    292425
    293426    return NULL;
  • trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.h

    r79524 r79563  
    2929
    3030
     31/**
     32 * The core of the DHCP server.
     33 *
     34 * This class is feed DhcpClientMessages that VBoxNetDhcpd has picked up from
     35 * the network.  After processing a message it returns the appropriate response
     36 * (if any) which VBoxNetDhcpd sends out.
     37 */
    3138class DHCPD
    3239{
    33     const Config *m_pConfig;
    34     RTCString m_strLeasesFileName;
    35     Db m_db;
     40    /** The DHCP configuration. */
     41    const Config   *m_pConfig;
     42    /** The lease database filename. */
     43    RTCString       m_strLeasesFilename;
     44    /** The lease database. */
     45    Db              m_db;
    3646
    3747public:
    3848    DHCPD();
    3949
    40     int init(const Config *);
     50    int init(const Config *) RT_NOEXCEPT;
    4151
    42     DhcpServerMessage *process(const std::unique_ptr<DhcpClientMessage> &req)
     52    DhcpServerMessage *process(const std::unique_ptr<DhcpClientMessage> &req) RT_NOEXCEPT
    4353    {
    44         if (req.get() == NULL)
    45             return NULL;
    46 
    47         return process(*req.get());
     54        if (req.get() != NULL)
     55            return process(*req.get());
     56        return NULL;
    4857    }
    4958
    50     DhcpServerMessage *process(DhcpClientMessage &req);
     59    DhcpServerMessage *process(DhcpClientMessage &req) RT_NOEXCEPT;
    5160
    5261private:
    53     DhcpServerMessage *doDiscover(DhcpClientMessage &req);
    54     DhcpServerMessage *doRequest(DhcpClientMessage &req);
    55     DhcpServerMessage *doInform(DhcpClientMessage &req);
     62    /** @name DHCP message processing methods
     63     * @{ */
     64    DhcpServerMessage *i_doDiscover(DhcpClientMessage &req);
     65    DhcpServerMessage *i_doRequest(DhcpClientMessage &req);
     66    DhcpServerMessage *i_doInform(DhcpClientMessage &req);
     67    DhcpServerMessage *i_doDecline(const DhcpClientMessage &req) RT_NOEXCEPT;
     68    DhcpServerMessage *i_doRelease(const DhcpClientMessage &req) RT_NOEXCEPT;
    5669
    57     DhcpServerMessage *doDecline(DhcpClientMessage &req);
    58     DhcpServerMessage *doRelease(DhcpClientMessage &req);
     70    DhcpServerMessage *i_createMessage(int type, DhcpClientMessage &req);
     71    /** @} */
    5972
    60     DhcpServerMessage *createMessage(int type, DhcpClientMessage &req);
    61 
    62     void loadLeases();
    63     void saveLeases();
     73    /** @name Lease database handling
     74     * @{ */
     75    int                i_loadLeases() RT_NOEXCEPT;
     76    void               i_saveLeases() RT_NOEXCEPT;
     77    /** @} */
    6478};
    6579
  • trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp

    r79530 r79563  
    3636 * Registers the ClientId format type callback ("%R[binding]").
    3737 */
    38 void Binding::registerFormat()
     38void Binding::registerFormat() RT_NOEXCEPT
    3939{
    4040    if (!g_fFormatRegistered)
     
    8787}
    8888
    89 const char *Binding::stateName() const
     89const char *Binding::stateName() const RT_NOEXCEPT
    9090{
    9191    switch (m_state)
     
    108108
    109109
    110 Binding &Binding::setState(const char *pszStateName)
     110Binding &Binding::setState(const char *pszStateName) RT_NOEXCEPT
    111111{
    112112    if (strcmp(pszStateName, "free") == 0)
     
    137137 * @param   tsDeadline          The expiry deadline to use.
    138138 */
    139 bool Binding::expire(Timestamp tsDeadline)
     139bool Binding::expire(Timestamp tsDeadline) RT_NOEXCEPT
    140140{
    141141    if (m_state <= Binding::EXPIRED)
     
    232232        /*
    233233         * Decode from "de:ad:be:ef".
    234          * XXX: RTStrConvertHexBytes() doesn't grok colons
    235234         */
    236         size_t cbBytes = strId.length() / 2;
    237         uint8_t *pBytes = new uint8_t[cbBytes];
    238         rc = RTStrConvertHexBytes(strId.c_str(), pBytes, cbBytes, 0);
     235        /** @todo RTStrConvertHexBytes() doesn't grok colons */
     236        size_t   cbBytes = strId.length() / 2;
     237        uint8_t *pbBytes = new uint8_t[cbBytes];
     238        rc = RTStrConvertHexBytes(strId.c_str(), pbBytes, cbBytes, 0);
    239239        if (RT_SUCCESS(rc))
    240240        {
    241             std::vector<uint8_t> rawopt(pBytes, pBytes + cbBytes);
    242             id = OptClientId(rawopt);
    243         }
    244         delete[] pBytes;
     241            try
     242            {
     243                std::vector<uint8_t> rawopt(pbBytes, pbBytes + cbBytes);
     244                id = OptClientId(rawopt);
     245            }
     246            catch (std::bad_alloc &)
     247            {
     248                delete[] pbBytes;
     249                throw;
     250            }
     251        }
     252        delete[] pbBytes;
    245253    }
    246254
     
    305313    }
    306314    else
    307     {   /* XXX: old code wrote timestamps instead of absolute time. */
     315    {   /** @todo XXX: old code wrote timestamps instead of absolute time. */
    308316        /* pretend that lease has just ended */
    309317        Timestamp fakeIssued = Timestamp::now();
     
    341349    m_pConfig = pConfig;
    342350
    343     m_pool.init(pConfig->getIPv4PoolFirst(),
    344                 pConfig->getIPv4PoolLast());
    345 
    346     return VINF_SUCCESS;
     351    return m_pool.init(pConfig->getIPv4PoolFirst(), pConfig->getIPv4PoolLast());
    347352}
    348353
     
    351356 * Expire old binding (leases).
    352357 */
    353 void Db::expire()
     358void Db::expire() RT_NOEXCEPT
    354359{
    355360    const Timestamp now = Timestamp::now();
     
    609614 * @param   pNewBinding     The new binding to add.
    610615 */
    611 int Db::i_addBinding(Binding *pNewBinding)
     616int Db::i_addBinding(Binding *pNewBinding) RT_NOEXCEPT
    612617{
    613618    /*
     
    662667 * @param   req                 The DHCP request.
    663668 */
    664 void Db::cancelOffer(const DhcpClientMessage &req)
     669void Db::cancelOffer(const DhcpClientMessage &req) RT_NOEXCEPT
    665670{
    666671    const OptRequestedAddress reqAddr(req);
     
    697702 * @param   req                 The DHCP request.
    698703 * @returns true if found and released, otherwise false.
    699  */
    700 bool Db::releaseBinding(const DhcpClientMessage &req)
     704 * @throws  nothing
     705 */
     706bool Db::releaseBinding(const DhcpClientMessage &req) RT_NOEXCEPT
    701707{
    702708    const RTNETADDRIPV4 addr = req.ciaddr();
     
    726732 * @param   strFilename         The file to write it to.
    727733 */
    728 int Db::writeLeases(const RTCString &strFilename) const
     734int Db::writeLeases(const RTCString &strFilename) const RT_NOEXCEPT
    729735{
    730736    LogDHCP(("writing leases to %s\n", strFilename.c_str()));
     737
     738    /** @todo This could easily be written directly to the file w/o going thru
     739     *        a xml::Document, xml::XmlFileWriter, hammering the heap and being
     740     *        required to catch a lot of different exceptions at various points.
     741     *        (RTStrmOpen, bunch of RTStrmPrintf using \%RMas and \%RMes.,
     742     *        RTStrmClose closely followed by a couple of renames.)
     743     */
    731744
    732745    /*
     
    789802 * @returns IPRT status code.
    790803 * @param   strFilename         The file to load it from.
    791  */
    792 int Db::loadLeases(const RTCString &strFilename)
     804 * @throws  nothing
     805 */
     806int Db::loadLeases(const RTCString &strFilename) RT_NOEXCEPT
    793807{
    794808    LogDHCP(("loading leases from %s\n", strFilename.c_str()));
     
    863877 * @return  IPRT status code.
    864878 */
    865 int Db::i_loadLease(const xml::ElementNode *pElmLease)
     879int Db::i_loadLease(const xml::ElementNode *pElmLease) RT_NOEXCEPT
    866880{
    867881    Binding *pBinding = NULL;
     
    878892        bool fExpired = pBinding->expire();
    879893        if (!fExpired)
    880             LogDHCP(("> LOAD: lease %R[binding]\n", pBinding));
     894            LogDHCP(("> LOAD:         lease %R[binding]\n", pBinding));
    881895        else
    882896            LogDHCP(("> LOAD: EXPIRED lease %R[binding]\n", pBinding));
  • trunk/src/VBox/NetworkServices/Dhcpd/Db.h

    r79531 r79563  
    3838
    3939/**
    40  * Address binding in the lease database.
     40 * An address binding in the lease database.
     41 *
     42 * This is how an allocated IPv4 address is mananged.
    4143 */
    4244class Binding
     
    6971    /** @name Attribute accessors
    7072     * @{ */
    71     RTNETADDRIPV4   addr() const        { return m_addr; }
     73    RTNETADDRIPV4   addr() const RT_NOEXCEPT        { return m_addr; }
    7274
    73     const ClientId &id() const          { return m_id; }
     75    const ClientId &id() const RT_NOEXCEPT          { return m_id; }
    7476
    75     uint32_t        leaseTime() const   { return m_secLease; }
    76     Timestamp       issued() const      { return m_issued; }
     77    uint32_t        leaseTime() const RT_NOEXCEPT   { return m_secLease; }
     78    Timestamp       issued() const RT_NOEXCEPT      { return m_issued; }
    7779
    78     State           state() const       { return m_state; }
    79     const char     *stateName() const;
    80     Binding        &setState(const char *pszStateName);
    81     Binding        &setState(State stateParam)
     80    State           state() const RT_NOEXCEPT       { return m_state; }
     81    const char     *stateName() const RT_NOEXCEPT;
     82    Binding        &setState(const char *pszStateName) RT_NOEXCEPT;
     83    Binding        &setState(State stateParam) RT_NOEXCEPT
    8284    {
    8385        m_state = stateParam;
     
    8789
    8890
    89     Binding &setLeaseTime(uint32_t secLease)
     91    Binding &setLeaseTime(uint32_t secLease) RT_NOEXCEPT
    9092    {
    9193        m_issued = Timestamp::now();
     
    9597
    9698    /** Reassigns the binding to the given client.   */
    97     Binding &giveTo(const ClientId &a_id)
     99    Binding &giveTo(const ClientId &a_id) RT_NOEXCEPT
    98100    {
    99101        m_id = a_id;
     
    108110    }
    109111
    110     bool expire(Timestamp tsDeadline);
    111     bool expire() { return expire(Timestamp::now()); }
     112    bool expire(Timestamp tsDeadline) RT_NOEXCEPT;
     113    bool expire() RT_NOEXCEPT
     114    {
     115        return expire(Timestamp::now());
     116    }
    112117
    113118    /** @name Serialization
     
    119124    /** @name String formatting of %R[binding].
    120125     * @{ */
    121     static void registerFormat();
     126    static void registerFormat() RT_NOEXCEPT;
    122127private:
    123128    static DECLCALLBACK(size_t) rtStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType,
     
    125130    static bool g_fFormatRegistered;
    126131    /** @} */
     132
     133    Binding &operator=(const Binding &); /**< Shuts up warning C4626 (incorrect warning?). */
    127134};
    128135
     
    130137/**
    131138 * The lease database.
     139 *
     140 * There is currently just one instance of this class in a running DHCP server
     141 * residing in Dhcpd::m_db.  It covers one single range of IPv4 addresses, which
     142 * currently unbound addressed are managed by m_pool.  The allocated addresses
     143 * are kept in the m_bindings list.  Once an address has been allocated, it will
     144 * stay in the m_bindings list even after released or expired.
    132145 */
    133146class Db
     
    151164
    152165    /** Check if @a addr belonges to this lease database. */
    153     bool     addressBelongs(RTNETADDRIPV4 addr) const { return m_pool.contains(addr); }
     166    bool     addressBelongs(RTNETADDRIPV4 addr) const RT_NOEXCEPT { return m_pool.contains(addr); }
    154167
    155168    Binding *allocateBinding(const DhcpClientMessage &req);
    156     bool     releaseBinding(const DhcpClientMessage &req);
     169    bool     releaseBinding(const DhcpClientMessage &req) RT_NOEXCEPT;
    157170
    158     void     cancelOffer(const DhcpClientMessage &req);
     171    void     cancelOffer(const DhcpClientMessage &req) RT_NOEXCEPT;
    159172
    160     void     expire();
     173    void     expire() RT_NOEXCEPT;
    161174
    162175    /** @name Database serialization methods
    163176     * @{ */
    164     int      loadLeases(const RTCString &strFilename);
     177    int      loadLeases(const RTCString &strFilename) RT_NOEXCEPT;
    165178private:
    166     int      i_loadLease(const xml::ElementNode *pElmLease);
     179    int      i_loadLease(const xml::ElementNode *pElmLease) RT_NOEXCEPT;
    167180public:
    168     int      writeLeases(const RTCString &strFilename) const;
     181    int      writeLeases(const RTCString &strFilename) const RT_NOEXCEPT;
    169182    /** @} */
    170183
     
    176189
    177190    /* add binding e.g. from the leases file */
    178     int      i_addBinding(Binding *pNewBinding);
     191    int      i_addBinding(Binding *pNewBinding) RT_NOEXCEPT;
    179192};
    180193
  • trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.cpp

    r79524 r79563  
    289289
    290290    bool fHeader = true;
    291     for (rawopts_t::const_iterator it = m_rawopts.begin();
    292          it != m_rawopts.end(); ++it)
     291    for (rawopts_t::const_iterator it = m_rawopts.begin(); it != m_rawopts.end(); ++it)
    293292    {
    294293        const uint8_t optcode = (*it).first;
  • trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.h

    r79524 r79563  
    6969    void setGiaddr(RTNETADDRIPV4 addr) { m_giaddr = addr; }
    7070
    71     uint8_t messageType() const
     71    uint8_t messageType() const RT_NOEXCEPT
    7272    {
    7373        Assert(m_optMessageType.present());
  • trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h

    r79553 r79563  
    5555
    5656  public:
    57     uint8_t optcode() const { return m_OptCode; }
    58     bool present() const { return m_fPresent; }
     57    uint8_t optcode() const RT_NOEXCEPT { return m_OptCode; }
     58    bool    present() const RT_NOEXCEPT { return m_fPresent; }
    5959
    6060  public:
  • trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.cpp

    r79531 r79563  
    2626
    2727
    28 int IPv4Pool::init(const IPv4Range &aRange)
     28int IPv4Pool::init(const IPv4Range &aRange) RT_NOEXCEPT
    2929{
    3030    AssertReturn(aRange.isValid(), VERR_INVALID_PARAMETER);
    3131
    3232    m_range = aRange;
    33     m_pool.insert(m_range);
     33    try
     34    {
     35        m_pool.insert(m_range);
     36    }
     37    catch (std::bad_alloc &)
     38    {
     39        return VERR_NO_MEMORY;
     40    }
    3441    return VINF_SUCCESS;
    3542}
    3643
    3744
    38 int IPv4Pool::init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr)
     45int IPv4Pool::init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT
    3946{
    4047    return init(IPv4Range(aFirstAddr, aLastAddr));
     
    4855 * @param   a_Range         The range to insert.
    4956 */
    50 int IPv4Pool::i_insert(const IPv4Range &a_Range)
     57int IPv4Pool::i_insert(const IPv4Range &a_Range) RT_NOEXCEPT
    5158{
    5259    /*
     
    8693     * No overlaps, insert it.
    8794     */
    88     m_pool.insert(itHint, a_Range);
     95    try
     96    {
     97        m_pool.insert(itHint, a_Range);
     98    }
     99    catch (std::bad_alloc &)
     100    {
     101        return VERR_NO_MEMORY;
     102    }
    89103    return VINF_SUCCESS;
    90104}
     
    114128            trimmed.FirstAddr += 1;
    115129            m_pool.erase(itBeg);
    116             m_pool.insert(trimmed);
     130            try
     131            {
     132                m_pool.insert(trimmed);
     133            }
     134            catch (std::bad_alloc &)
     135            {
     136                /** @todo r=bird: Theortically the insert could fail with a bad_alloc and we'd
     137                 * drop a range of IP address.  It would be nice if we could safely modify itBit
     138                 * without having to re-insert it.  The author of this code (not bird) didn't
     139                 * seem to think this safe?
     140                 *
     141                 * If we want to play safe and all that, just use a AVLRU32TREE (or AVLRU64TREE
     142                 * if lazy) AVL tree from IPRT.  Since we know exactly how it's implemented and
     143                 * works, there will be no uncertanties like this when using it (both here
     144                 * and in the i_insert validation logic). */
     145                LogRelFunc(("Caught bad_alloc! We're truely buggered now!\n"));
     146            }
    117147        }
    118148    }
  • trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.h

    r79531 r79563  
    4040    IPV4HADDR LastAddr;        /**< Higest address (inclusive). */
    4141
    42     IPv4Range()
     42    IPv4Range() RT_NOEXCEPT
    4343        : FirstAddr(0), LastAddr(0)
    4444    {}
    4545
    46     explicit IPv4Range(IPV4HADDR aSingleAddr)
     46    explicit IPv4Range(IPV4HADDR aSingleAddr) RT_NOEXCEPT
    4747        : FirstAddr(aSingleAddr), LastAddr(aSingleAddr)
    4848    {}
    4949
    50     IPv4Range(IPV4HADDR aFirstAddr, IPV4HADDR aLastAddr)
     50    IPv4Range(IPV4HADDR aFirstAddr, IPV4HADDR aLastAddr) RT_NOEXCEPT
    5151        : FirstAddr(aFirstAddr), LastAddr(aLastAddr)
    5252    {}
    5353
    54     explicit IPv4Range(RTNETADDRIPV4 aSingleAddr)
     54    explicit IPv4Range(RTNETADDRIPV4 aSingleAddr) RT_NOEXCEPT
    5555        : FirstAddr(RT_N2H_U32(aSingleAddr.u)), LastAddr(RT_N2H_U32(aSingleAddr.u))
    5656    {}
    5757
    58     IPv4Range(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr)
     58    IPv4Range(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT
    5959        : FirstAddr(RT_N2H_U32(aFirstAddr.u)), LastAddr(RT_N2H_U32(aLastAddr.u))
    6060    {}
    6161
    62     bool isValid() const
     62    bool isValid() const RT_NOEXCEPT
    6363    {
    6464        return FirstAddr <= LastAddr;
    6565    }
    6666
    67     bool contains(IPV4HADDR addr) const
     67    bool contains(IPV4HADDR addr) const RT_NOEXCEPT
    6868    {
    6969        return FirstAddr <= addr && addr <= LastAddr;
    7070    }
    7171
    72     bool contains(RTNETADDRIPV4 addr) const
     72    bool contains(RTNETADDRIPV4 addr) const RT_NOEXCEPT
    7373    {
    7474        return contains(RT_N2H_U32(addr.u));
     
    7676
    7777    /** Checks if this range includes the @a a_rRange. */
    78     bool contains(const IPv4Range &a_rRange) const
     78    bool contains(const IPv4Range &a_rRange) const RT_NOEXCEPT
    7979    {
    8080        return a_rRange.isValid()
     
    8585
    8686
    87 inline bool operator==(const IPv4Range &l, const IPv4Range &r)
     87inline bool operator==(const IPv4Range &l, const IPv4Range &r) RT_NOEXCEPT
    8888{
    8989    return l.FirstAddr == r.FirstAddr && l.LastAddr == r.LastAddr;
     
    9191
    9292
    93 inline bool operator<(const IPv4Range &l, const IPv4Range &r)
     93inline bool operator<(const IPv4Range &l, const IPv4Range &r)  RT_NOEXCEPT
    9494{
    9595    return l.LastAddr < r.FirstAddr;
     
    118118    {}
    119119
    120     int init(const IPv4Range &aRange);
    121     int init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr);
     120    int init(const IPv4Range &aRange) RT_NOEXCEPT;
     121    int init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT;
    122122
    123123    RTNETADDRIPV4 allocate();
     
    127127     * Checks if the pool range includes @a addr (allocation status not considered).
    128128     */
    129     bool contains(RTNETADDRIPV4 addr) const
     129    bool contains(RTNETADDRIPV4 addr) const RT_NOEXCEPT
    130130    {
    131131        return m_range.contains(addr);
     
    133133
    134134private:
    135     int i_insert(const IPv4Range &range);
     135    int i_insert(const IPv4Range &range) RT_NOEXCEPT;
    136136#if 0
    137     int i_insert(IPV4HADDR single)                            { return i_insert(IPv4Range(single)); }
     137    int i_insert(IPV4HADDR single) RT_NOEXCEPT                          { return i_insert(IPv4Range(single)); }
    138138#endif
    139     int i_insert(IPV4HADDR first, IPV4HADDR last)             { return i_insert(IPv4Range(first, last)); }
    140     int i_insert(RTNETADDRIPV4 single)                        { return i_insert(IPv4Range(single)); }
    141     int i_insert(RTNETADDRIPV4 first, RTNETADDRIPV4 last)     { return i_insert(IPv4Range(first, last)); }
     139    int i_insert(IPV4HADDR first, IPV4HADDR last) RT_NOEXCEPT           { return i_insert(IPv4Range(first, last)); }
     140    int i_insert(RTNETADDRIPV4 single) RT_NOEXCEPT                      { return i_insert(IPv4Range(single)); }
     141    int i_insert(RTNETADDRIPV4 first, RTNETADDRIPV4 last) RT_NOEXCEPT   { return i_insert(IPv4Range(first, last)); }
    142142};
    143143
  • trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.cpp

    r79526 r79563  
    2424
    2525
    26 size_t Timestamp::strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const
     26size_t Timestamp::strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const RT_NOEXCEPT
    2727{
    2828    RTTIMESPEC TimeSpec;
  • trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.h

    r79530 r79563  
    3939
    4040public:
    41     Timestamp()
     41    Timestamp() RT_NOEXCEPT
    4242    {
    4343        RTTimeSpecSetNano(&m_TimeSpec, 0);
    4444    }
    4545
    46     Timestamp(PCRTTIMESPEC a_pTimeSpec)
     46    Timestamp(PCRTTIMESPEC a_pTimeSpec) RT_NOEXCEPT
    4747    {
    4848        m_TimeSpec = *a_pTimeSpec;
     
    5050
    5151    /** Get a timestamp initialized to current time. */
    52     static Timestamp now()
     52    static Timestamp now() RT_NOEXCEPT
    5353    {
    5454        RTTIMESPEC Tmp;
     
    5757
    5858    /** Get a timestamp with the given value in seconds since unix epoch. */
    59     static Timestamp absSeconds(int64_t secTimestamp)
     59    static Timestamp absSeconds(int64_t secTimestamp) RT_NOEXCEPT
    6060    {
    6161        RTTIMESPEC Tmp;
     
    6363    }
    6464
    65     Timestamp &addSeconds(int64_t cSecs)
     65    Timestamp &addSeconds(int64_t cSecs) RT_NOEXCEPT
    6666    {
    6767        RTTimeSpecAddSeconds(&m_TimeSpec, cSecs);
     
    6969    }
    7070
    71     Timestamp &subSeconds(int64_t cSecs)
     71    Timestamp &subSeconds(int64_t cSecs) RT_NOEXCEPT
    7272    {
    7373        RTTimeSpecSubSeconds(&m_TimeSpec, cSecs);
     
    7575    }
    7676
    77     RTTIMESPEC *getAbsTimeSpec(RTTIMESPEC *pTime) const
     77    RTTIMESPEC *getAbsTimeSpec(RTTIMESPEC *pTime) const RT_NOEXCEPT
    7878    {
    7979        *pTime = m_TimeSpec;
     
    8181    }
    8282
    83     int64_t getAbsSeconds() const
     83    int64_t getAbsSeconds() const RT_NOEXCEPT
    8484    {
    8585        return RTTimeSpecGetSeconds(&m_TimeSpec);
     
    8787
    8888    /** Only for log formatting. */
    89     size_t strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const;
     89    size_t strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const RT_NOEXCEPT;
    9090
    91     int compare(const Timestamp &a_rRight) const
     91    int compare(const Timestamp &a_rRight) const RT_NOEXCEPT
    9292    {
    9393        return RTTimeSpecCompare(&m_TimeSpec, &a_rRight.m_TimeSpec);
    9494    }
    9595
    96     friend bool operator<( const Timestamp &, const Timestamp &);
    97     friend bool operator>( const Timestamp &, const Timestamp &);
    98     friend bool operator==(const Timestamp &, const Timestamp &);
    99     friend bool operator!=(const Timestamp &, const Timestamp &);
    100     friend bool operator<=(const Timestamp &, const Timestamp &);
    101     friend bool operator>=(const Timestamp &, const Timestamp &);
     96    friend bool operator<( const Timestamp &, const Timestamp &) RT_NOEXCEPT;
     97    friend bool operator>( const Timestamp &, const Timestamp &) RT_NOEXCEPT;
     98    friend bool operator==(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
     99    friend bool operator!=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
     100    friend bool operator<=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
     101    friend bool operator>=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
    102102};
    103103
    104104
    105 inline bool operator<( const Timestamp &l, const Timestamp &r) { return l.compare(r) < 0; }
    106 inline bool operator>( const Timestamp &l, const Timestamp &r) { return l.compare(r) > 0; }
    107 inline bool operator==(const Timestamp &l, const Timestamp &r) { return l.compare(r) == 0; }
    108 inline bool operator!=(const Timestamp &l, const Timestamp &r) { return l.compare(r) != 0; }
    109 inline bool operator<=(const Timestamp &l, const Timestamp &r) { return l.compare(r) <= 0; }
    110 inline bool operator>=(const Timestamp &l, const Timestamp &r) { return l.compare(r) >= 0; }
     105inline bool operator<( const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) < 0; }
     106inline bool operator>( const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) > 0; }
     107inline bool operator==(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) == 0; }
     108inline bool operator!=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) != 0; }
     109inline bool operator<=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) <= 0; }
     110inline bool operator>=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) >= 0; }
    111111
    112112#endif /* !VBOX_INCLUDED_SRC_Dhcpd_Timestamp_h */
  • trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp

    r79524 r79563  
    372372    {
    373373        int rc = ifWait();
    374 
    375         if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
    376             continue;
    377 
     374        if (   rc != VERR_INTERRUPTED
    378375#if 0 /* we wait indefinitely */
    379         if (rc == VERR_TIMEOUT)
    380             ...;
     376            && rc != VERR_TIMEOUT
    381377#endif
    382 
    383         if (RT_FAILURE(rc))
     378            )
     379            ifProcessInput();
     380        else
     381        {
     382            LogRel(("ifWait failed: %Rrc\n", rc));
     383            RTMsgError("ifWait failed: %Rrc", rc);
    384384            return;
    385 
    386         ifProcessInput();
     385        }
    387386    }
    388387}
     
    613612int VBoxNetDhcpd::main(int argc, char **argv)
    614613{
    615     int rc;
    616 
     614    /*
     615     * Register string format types.
     616     */
    617617    ClientId::registerFormat();
    618 
    619     /* XXX: We no longer need hardcoded and compat methods. We should remove them soon. */
     618    Binding::registerFormat();
     619
     620    /*
     621     * Parse the command line into a configuration object.
     622     */
     623    /** @todo XXX: We no longer need hardcoded and compat methods. We should remove them soon. */
    620624    if (argc < 2)
    621625        m_Config = Config::hardcoded();
     
    624628        m_Config = Config::create(argc, argv);
    625629    else
    626         m_Config = Config::compat(argc, argv);
    627 
     630    {
     631        try
     632        {
     633            m_Config = Config::compat(argc, argv);
     634        }
     635        catch (std::bad_alloc &)
     636        {
     637            m_Config = NULL;
     638            RTMsgError("Out of memory");
     639            return VERR_NO_MEMORY;
     640        }
     641    }
    628642    if (m_Config == NULL)
    629643        return VERR_GENERAL_FAILURE;
    630644
    631     rc = m_server.init(m_Config);
    632 
    633     /* connect to the intnet */
    634     rc = ifInit(m_Config->getNetwork(),
    635                 m_Config->getTrunk(),
    636                 m_Config->getTrunkType());
    637     if (RT_FAILURE(rc))
    638         return rc;
    639 
    640     /* setup lwip */
    641     rc = vboxLwipCoreInitialize(lwipInitCB, this);
    642     if (RT_FAILURE(rc))
    643         return rc;
    644 
    645     ifPump();
    646     return VINF_SUCCESS;
     645    /*
     646     * Initialize the server.
     647     */
     648    int rc = m_server.init(m_Config);
     649    if (RT_SUCCESS(rc))
     650    {
     651        /* connect to the intnet */
     652        rc = ifInit(m_Config->getNetwork(), m_Config->getTrunk(), m_Config->getTrunkType());
     653        if (RT_SUCCESS(rc))
     654        {
     655            /* setup lwip */
     656            rc = vboxLwipCoreInitialize(lwipInitCB, this);
     657            if (RT_SUCCESS(rc))
     658            {
     659                /*
     660                 * Pump packets more or less for ever.
     661                 */
     662                ifPump();
     663            }
     664            else
     665                RTMsgError("Terminating - vboxLwipCoreInitialize failed: %Rrc", rc);
     666        }
     667        else
     668            RTMsgError("Terminating - ifInit failed: %Rrc", rc);
     669    }
     670    else
     671        RTMsgError("Terminating - Dhcpd::init failed: %Rrc", rc);
     672    return rc;
    647673}
    648674
     
    707733                             ip_addr_t *addr, u16_t port)
    708734{
    709     err_t error;
    710     int rc;
    711 
    712735    RT_NOREF(pcb, addr, port);
    713736
     
    735758
    736759    octets_t data;
    737     rc = msgOut->encode(data);
     760    int rc = msgOut->encode(data);
    738761    if (RT_FAILURE(rc))
    739762        return;
     
    743766        return;
    744767
    745     error = pbuf_take(q.get(), &data.front(), (u16_t)data.size());
     768    err_t error = pbuf_take(q.get(), &data.front(), (u16_t)data.size());
    746769    if (error != ERR_OK)
    747770        return;
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