Index: /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.cpp	(revision 79563)
@@ -34,5 +34,5 @@
  * Registers the ClientId format type callback ("%R[id]").
  */
-void ClientId::registerFormat()
+void ClientId::registerFormat() RT_NOEXCEPT
 {
     if (!g_fFormatRegistered)
@@ -82,5 +82,5 @@
 
 
-bool operator==(const ClientId &l, const ClientId &r)
+bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT
 {
     if (l.m_id.present())
@@ -99,5 +99,5 @@
 
 
-bool operator<(const ClientId &l, const ClientId &r)
+bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT
 {
     if (l.m_id.present())
Index: /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/ClientId.h	(revision 79563)
@@ -41,10 +41,13 @@
         : m_mac(), m_id()
     {}
+    /** @throws std::bad_alloc */
     ClientId(const RTMAC &a_mac, const OptClientId &a_id)
         : m_mac(a_mac), m_id(a_id)
     {}
+    /** @throws std::bad_alloc */
     ClientId(const ClientId &a_rThat)
         : m_mac(a_rThat.m_mac), m_id(a_rThat.m_id)
     {}
+    /** @throws std::bad_alloc */
     ClientId &operator=(const ClientId &a_rThat)
     {
@@ -54,10 +57,10 @@
     }
 
-    const RTMAC       &mac() const  { return m_mac; }
-    const OptClientId &id() const   { return m_id; }
+    const RTMAC       &mac() const RT_NOEXCEPT  { return m_mac; }
+    const OptClientId &id() const RT_NOEXCEPT   { return m_id; }
 
     /** @name String formatting of %R[id].
      * @{ */
-    static void registerFormat();
+    static void registerFormat() RT_NOEXCEPT;
 private:
     static DECLCALLBACK(size_t) rtStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType,
@@ -66,12 +69,12 @@
     /** @} */
 
-    friend bool operator==(const ClientId &l, const ClientId &r);
-    friend bool operator<(const ClientId &l, const ClientId &r);
+    friend bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
+    friend bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
 };
 
-bool operator==(const ClientId &l, const ClientId &r);
-bool operator<(const ClientId &l, const ClientId &r);
+bool operator==(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
+bool operator<(const ClientId &l, const ClientId &r) RT_NOEXCEPT;
 
-inline bool operator!=(const ClientId &l, const ClientId &r)
+inline bool operator!=(const ClientId &l, const ClientId &r) RT_NOEXCEPT
 {
     return !(l == r);
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp	(revision 79563)
@@ -88,5 +88,5 @@
  * @returns IPRT status code.
  */
-int Config::i_init()
+int Config::i_init() RT_NOEXCEPT
 {
     return i_homeInit();
@@ -100,5 +100,5 @@
  * @todo Too many init functions?
  */
-int Config::i_homeInit()
+int Config::i_homeInit() RT_NOEXCEPT
 {
     char szHome[RTPATH_MAX];
@@ -121,5 +121,5 @@
  * @returns Config instance on success, NULL on failure.
  */
-/*static*/ Config *Config::i_createInstanceAndCallInit()
+/*static*/ Config *Config::i_createInstanceAndCallInit() RT_NOEXCEPT
 {
     Config *pConfig;
@@ -161,4 +161,6 @@
  * Interal worker for i_setNetwork() that sets m_strBaseName to sanitized the
  * version of m_strNetwork suitable for use as a path component.
+ *
+ * @throws std::bad_alloc
  */
 void Config::i_sanitizeBaseName()
@@ -196,5 +198,5 @@
  * @todo make the log file directly configurable?
  */
-int Config::i_logInit()
+int Config::i_logInit() RT_NOEXCEPT
 {
     if (m_strHome.isEmpty() || m_strBaseName.isEmpty())
@@ -241,5 +243,5 @@
  * Post process and validate the configuration after it has been loaded.
  */
-int Config::i_complete()
+int Config::i_complete() RT_NOEXCEPT
 {
     if (m_strNetwork.isEmpty())
@@ -336,5 +338,5 @@
 
 
-/*static*/ Config *Config::hardcoded()
+/*static*/ Config *Config::hardcoded() RT_NOEXCEPT
 {
     std::unique_ptr<Config> config(i_createInstanceAndCallInit());
@@ -378,5 +380,9 @@
 
 
-
+/**
+ * Old VBoxNetDHCP style command line parsing.
+ *
+ * @throws std::bad_alloc
+ */
 /*static*/ Config *Config::compat(int argc, char **argv)
 {
@@ -519,11 +525,10 @@
 
 
-Config *Config::create(int argc, char **argv)
-{
-#define DHCPD_GETOPT_COMMENT 256 /* No short option for --comment */
+Config *Config::create(int argc, char **argv) RT_NOEXCEPT
+{
     static const RTGETOPTDEF s_aOptions[] =
     {
-        { "--config",       'c',                  RTGETOPT_REQ_STRING },
-        { "--comment",      DHCPD_GETOPT_COMMENT, RTGETOPT_REQ_STRING }
+        { "--config",       'c', RTGETOPT_REQ_STRING },
+        { "--comment",      '#', RTGETOPT_REQ_STRING }
     };
 
@@ -556,5 +561,5 @@
                 break;
 
-            case DHCPD_GETOPT_COMMENT: /* --comment */
+            case '#': /* --comment */
                 /* The sole purpose of this option is to allow identification of DHCP
                  * server instances in the process list. We ignore the required string
@@ -589,5 +594,5 @@
  * @note The release log has is not operational when this method is called.
  */
-Config *Config::i_read(const char *pszFileName)
+Config *Config::i_read(const char *pszFileName) RT_NOEXCEPT
 {
     if (pszFileName == NULL || pszFileName[0] == '\0')
@@ -635,4 +640,10 @@
         return NULL;
     }
+    catch (std::bad_alloc &)
+    {
+        LogFunc(("std::bad_alloc\n"));
+        RTMsgError("std::bad_alloc reading config\n");
+        return NULL;
+    }
     catch (...)
     {
@@ -650,5 +661,6 @@
  * below it.
  *
- * @throws stuff.
+ * @param   pElmRoot    The root element.
+ * @throws  std::bad_alloc, ConfigFileError
  */
 void Config::i_parseConfig(const xml::ElementNode *pElmRoot)
@@ -694,5 +706,5 @@
  *
  * @param   pElmServer          The DHCPServer element.
- * @throws  ConfigFileError
+ * @throws  std::bad_alloc, ConfigFileError
  */
 void Config::i_parseServer(const xml::ElementNode *pElmServer)
@@ -767,5 +779,5 @@
  *
  * @param   pElmServer          The <Options> element.
- * @throws  ConfigFileError
+ * @throws  std::bad_alloc, ConfigFileError
  */
 void Config::i_parseGlobalOptions(const xml::ElementNode *options)
@@ -792,5 +804,5 @@
  *
  * @param   pElmServer          The <Config> element.
- * @throws  ConfigFileError
+ * @throws  std::bad_alloc, ConfigFileError
  */
 void Config::i_parseVMConfig(const xml::ElementNode *pElmConfig)
@@ -841,5 +853,5 @@
  * @param   pElmServer          The <Option> element.
  * @param   optmap              The option map to add the option to.
- * @throws  ConfigFileError
+ * @throws  std::bad_alloc, ConfigFileError
  */
 void Config::i_parseOption(const xml::ElementNode *pElmOption, optmap_t &optmap)
@@ -946,4 +958,6 @@
  * @param   idVendorClass   The vendor class ID.
  * @param   idUserClass     The user class ID.
+ *
+ * @throws  std::bad_alloc
  */
 optmap_t &Config::getOptions(optmap_t &a_rRetOpts, const OptParameterRequest &reqOpts, const ClientId &id,
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Config.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Config.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Config.h	(revision 79563)
@@ -72,35 +72,35 @@
     Config();
 
-    int                 i_init();
-    int                 i_homeInit();
-    static Config      *i_createInstanceAndCallInit();
-    int                 i_logInit();
-    int                 i_complete();
+    int                 i_init() RT_NOEXCEPT;
+    int                 i_homeInit() RT_NOEXCEPT;
+    static Config      *i_createInstanceAndCallInit() RT_NOEXCEPT;
+    int                 i_logInit() RT_NOEXCEPT;
+    int                 i_complete() RT_NOEXCEPT;
 
 public:
     /** @name Factory methods
      * @{ */
-    static Config      *hardcoded();                   /**< For testing. */
-    static Config      *create(int argc, char **argv); /**< --config */
-    static Config      *compat(int argc, char **argv); /**< Old VBoxNetDHCP command line parsing. */
+    static Config      *hardcoded() RT_NOEXCEPT;                    /**< For testing. */
+    static Config      *create(int argc, char **argv) RT_NOEXCEPT;  /**< --config */
+    static Config      *compat(int argc, char **argv);
     /** @} */
 
     /** @name Accessors
      * @{ */
-    const RTCString    &getHome() const             { return m_strHome; }
+    const RTCString    &getHome() const RT_NOEXCEPT             { return m_strHome; }
 
-    const RTCString    &getNetwork() const          { return m_strNetwork; }
+    const RTCString    &getNetwork() const RT_NOEXCEPT          { return m_strNetwork; }
 
-    const RTCString    &getBaseName() const         { return m_strBaseName; }
-    const RTCString    &getTrunk() const            { return m_strTrunk; }
-    INTNETTRUNKTYPE     getTrunkType() const        { return m_enmTrunkType; }
+    const RTCString    &getBaseName() const RT_NOEXCEPT         { return m_strBaseName; }
+    const RTCString    &getTrunk() const RT_NOEXCEPT            { return m_strTrunk; }
+    INTNETTRUNKTYPE     getTrunkType() const RT_NOEXCEPT        { return m_enmTrunkType; }
 
-    const RTMAC        &getMacAddress() const       { return m_MacAddress; }
+    const RTMAC        &getMacAddress() const RT_NOEXCEPT       { return m_MacAddress; }
 
-    RTNETADDRIPV4       getIPv4Address() const      { return m_IPv4Address; }
-    RTNETADDRIPV4       getIPv4Netmask() const      { return m_IPv4Netmask; }
+    RTNETADDRIPV4       getIPv4Address() const RT_NOEXCEPT      { return m_IPv4Address; }
+    RTNETADDRIPV4       getIPv4Netmask() const RT_NOEXCEPT      { return m_IPv4Netmask; }
 
-    RTNETADDRIPV4       getIPv4PoolFirst() const    { return m_IPv4PoolFirst; }
-    RTNETADDRIPV4       getIPv4PoolLast() const     { return m_IPv4PoolLast; }
+    RTNETADDRIPV4       getIPv4PoolFirst() const RT_NOEXCEPT    { return m_IPv4PoolFirst; }
+    RTNETADDRIPV4       getIPv4PoolLast() const RT_NOEXCEPT     { return m_IPv4PoolLast; }
     /** @} */
 
@@ -112,5 +112,5 @@
     /** @name Configuration file reading and parsing
      * @{ */
-    static Config      *i_read(const char *pszFileName);
+    static Config      *i_read(const char *pszFileName) RT_NOEXCEPT;
     void                i_parseConfig(const xml::ElementNode *root);
     void                i_parseServer(const xml::ElementNode *server);
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.cpp	(revision 79563)
@@ -16,9 +16,14 @@
  */
 
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
 #include "DhcpdInternal.h"
 #include "DHCPD.h"
 #include "DhcpOptions.h"
 
-#include <iprt/path.h>
+#include <iprt/message.h>
+#include <iprt/cpp/path.h>
 
 
@@ -29,10 +34,14 @@
 
 
-int DHCPD::init(const Config *pConfig)
-{
-    int rc;
-
-    if (m_pConfig != NULL)
-        return VERR_INVALID_STATE;
+/**
+ * Initializes the DHCPD with the given config.
+ *
+ * @returns VBox status code.
+ * @param   pConfig     The configuration to use.
+ */
+int DHCPD::init(const Config *pConfig) RT_NOEXCEPT
+{
+    Assert(pConfig);
+    AssertReturn(!m_pConfig, VERR_INVALID_STATE);
 
     /** @todo r=bird: This must be configurable so main can read the database and
@@ -40,48 +49,100 @@
      * figuring  out the IP address of a VM.) */
 
-    /* leases file name */
-    m_strLeasesFileName = pConfig->getHome();
-    m_strLeasesFileName += RTPATH_DELIMITER;
-    m_strLeasesFileName += pConfig->getBaseName();
-    m_strLeasesFileName += "-Dhcpd.leases";
-
-    rc = m_db.init(pConfig);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    loadLeases();
-
-    m_pConfig = pConfig;
-    return VINF_SUCCESS;
-}
-
-
-void DHCPD::loadLeases()
-{
-    m_db.loadLeases(m_strLeasesFileName);
-}
-
-
-void DHCPD::saveLeases()
+    /* leases filename */
+    int rc = m_strLeasesFilename.assignNoThrow(pConfig->getHome());
+    if (RT_SUCCESS(rc))
+        rc = RTPathAppendCxx(m_strLeasesFilename, pConfig->getBaseName());
+    if (RT_SUCCESS(rc))
+        rc = m_strLeasesFilename.appendNoThrow("-Dhcpd.leases");
+    if (RT_SUCCESS(rc))
+    {
+        /* Load the lease database, ignoring most issues except being out of memory: */
+        rc = m_db.init(pConfig);
+        if (RT_SUCCESS(rc))
+        {
+            rc = i_loadLeases();
+            if (rc != VERR_NO_MEMORY)
+            {
+                m_pConfig = pConfig;
+                rc = VINF_SUCCESS;
+            }
+            else
+            {
+                LogRel(("Ran out of memory loading leases from '%s'.  Try rename or delete the file.\n",
+                        m_strLeasesFilename.c_str()));
+                RTMsgError("Ran out of memory loading leases from '%s'.  Try rename or delete the file.\n",
+                           m_strLeasesFilename.c_str());
+            }
+        }
+    }
+    return rc;
+}
+
+
+/**
+ * Load leases from m_strLeasesFilename.
+ */
+int DHCPD::i_loadLeases() RT_NOEXCEPT
+{
+    return m_db.loadLeases(m_strLeasesFilename);
+}
+
+
+/**
+ * Save the current leases to m_strLeasesFilename, doing expiry first.
+ *
+ * This is called after m_db is updated during a client request, so the on disk
+ * database is always up-to-date.   This means it doesn't matter if we're
+ * terminated with extreme prejudice, and it allows Main to look up IP addresses
+ * for VMs.
+ *
+ * @throws nothing
+ */
+void DHCPD::i_saveLeases() RT_NOEXCEPT
 {
     m_db.expire();
-    m_db.writeLeases(m_strLeasesFileName);
-}
-
-
-DhcpServerMessage *DHCPD::process(DhcpClientMessage &req)
-{
-    DhcpServerMessage *reply = NULL;
-
-    req.dump();
-
+    m_db.writeLeases(m_strLeasesFilename);
+}
+
+
+/**
+ * Process a DHCP client message.
+ *
+ * Called by VBoxNetDhcpd::dhcp4Recv().
+ *
+ * @returns Pointer to DHCP reply (caller deletes this).  NULL if no reply
+ *          warranted or we're out of memory.
+ * @param   req                 The client message.
+ * @throws  nothing
+ */
+DhcpServerMessage *DHCPD::process(DhcpClientMessage &req) RT_NOEXCEPT
+{
+    /*
+     * Dump the package if release log level 3+1 are enable or if debug logging is
+     * enabled.  We don't normally want to do this at the default log level, of course.
+     */
+    if ((LogRelIs3Enabled() && LogRelIsEnabled()) || LogIsEnabled())
+        req.dump();
+
+    /*
+     * Fend off requests that are not for us.
+     */
     OptServerId sid(req);
     if (sid.present() && sid.value().u != m_pConfig->getIPv4Address().u)
     {
         if (req.broadcasted() && req.messageType() == RTNET_DHCP_MT_REQUEST)
+        {
+            LogRel2(("Message is not for us, canceling any pending offer.\n"));
             m_db.cancelOffer(req);
-
-        return NULL;
-    }
+        }
+        else
+            LogRel2(("Message is not for us.\n"));
+        return NULL;
+    }
+
+    /*
+     * Process it.
+     */
+    DhcpServerMessage *reply = NULL;
 
     switch (req.messageType())
@@ -91,13 +152,34 @@
          */
         case RTNET_DHCP_MT_DISCOVER:
-            reply = doDiscover(req);
+            try
+            {
+                reply = i_doDiscover(req);
+            }
+            catch (std::bad_alloc &)
+            {
+                LogRelFunc(("i_doDiscover threw bad_alloc\n"));
+            }
             break;
 
         case RTNET_DHCP_MT_REQUEST:
-            reply = doRequest(req);
+            try
+            {
+                reply = i_doRequest(req);
+            }
+            catch (std::bad_alloc &)
+            {
+                LogRelFunc(("i_doRequest threw bad_alloc\n"));
+            }
             break;
 
         case RTNET_DHCP_MT_INFORM:
-            reply = doInform(req);
+            try
+            {
+                reply = i_doInform(req);
+            }
+            catch (std::bad_alloc &)
+            {
+                LogRelFunc(("i_doInform threw bad_alloc\n"));
+            }
             break;
 
@@ -106,9 +188,9 @@
          */
         case RTNET_DHCP_MT_DECLINE:
-            doDecline(req);
+            i_doDecline(req);
             break;
 
         case RTNET_DHCP_MT_RELEASE:
-            doRelease(req);
+            i_doRelease(req);
             break;
 
@@ -116,8 +198,15 @@
          * Unexpected or unknown message types.
          */
-        case RTNET_DHCP_MT_OFFER: /* FALLTHROUGH */
-        case RTNET_DHCP_MT_ACK:   /* FALLTHROUGH */
-        case RTNET_DHCP_MT_NAC:   /* FALLTHROUGH */
+        case RTNET_DHCP_MT_OFFER:
+            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_OFFER!\n"));
+            break;
+        case RTNET_DHCP_MT_ACK:
+            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_ACK!\n"));
+            break;
+        case RTNET_DHCP_MT_NAC:
+            LogRel2(("Ignoring unexpected message of type RTNET_DHCP_MT_NAC!\n"));
+            break;
         default:
+            LogRel2(("Ignoring unexpected message of unknown type: %d (%#x)!\n", req.messageType(), req.messageType()));
             break;
     }
@@ -127,5 +216,10 @@
 
 
-DhcpServerMessage *DHCPD::createMessage(int type, DhcpClientMessage &req)
+/**
+ * Internal helper.
+ *
+ * @throws  std::bad_alloc
+ */
+DhcpServerMessage *DHCPD::i_createMessage(int type, DhcpClientMessage &req)
 {
     return new DhcpServerMessage(req, type, m_pConfig->getIPv4Address());
@@ -133,7 +227,31 @@
 
 
-DhcpServerMessage *DHCPD::doDiscover(DhcpClientMessage &req)
-{
-    /*
+/**
+ * 4.3.1 DHCPDISCOVER message
+ *
+ * When a server receives a DHCPDISCOVER message from a client, the server
+ * chooses a network address for the requesting client. If no address is
+ * available, the server may choose to report the problem to the system
+ * administrator. If an address is available, the new address SHOULD be chosen
+ * as follows:
+ *  - The client's current address as recorded in the client's current binding,
+ *    ELSE
+ *  - The client's previous address as recorded in the client's (now expired or
+ *    released) binding, if that address is in the server's pool of available
+ *    addresses and not already allocated, ELSE
+ *  - The address requested in the 'Requested IP Address' option, if that
+ *    address is valid and not already allocated, ELSE
+ *  - A new address allocated from the server's pool of available addresses;
+ *    the address is selected based on the subnet from which the message was
+ *    received (if 'giaddr' is 0) or on the address of the relay agent that
+ *    forwarded the message ('giaddr' when not 0).
+ *
+ * ...
+ *
+ * @throws  std::bad_alloc
+ */
+DhcpServerMessage *DHCPD::i_doDiscover(DhcpClientMessage &req)
+{
+    /** @todo
      * XXX: TODO: Windows iSCSI initiator sends DHCPDISCOVER first and
      * it has ciaddr filled.  Shouldn't let it screw up the normal
@@ -148,5 +266,4 @@
         return NULL;
 
-
     std::unique_ptr<DhcpServerMessage> reply;
 
@@ -154,18 +271,18 @@
     if (!fRapidCommit)
     {
-        reply.reset(createMessage(RTNET_DHCP_MT_OFFER, req));
+        reply.reset(i_createMessage(RTNET_DHCP_MT_OFFER, req));
 
         if (b->state() < Binding::OFFERED)
             b->setState(Binding::OFFERED);
 
-        /* use small lease time internally to quickly free unclaimed offers? */
+        /** @todo use small lease time internally to quickly free unclaimed offers? */
     }
     else
     {
-        reply.reset(createMessage(RTNET_DHCP_MT_ACK, req));
+        reply.reset(i_createMessage(RTNET_DHCP_MT_ACK, req));
         reply->addOption(OptRapidCommit(true));
 
         b->setState(Binding::ACKED);
-        saveLeases();
+        i_saveLeases();
     }
 
@@ -178,10 +295,27 @@
     reply->addOptions(m_pConfig->getOptions(replyOptions, optlist, req.clientId()));
 
-    // reply->maybeUnicast(req); /* XXX: we reject ciaddr != 0 above */
+    // reply->maybeUnicast(req); /** @todo XXX: we reject ciaddr != 0 above */
     return reply.release();
 }
 
 
-DhcpServerMessage *DHCPD::doRequest(DhcpClientMessage &req)
+/**
+ * 4.3.2 DHCPREQUEST message
+ *
+ * A DHCPREQUEST message may come from a client responding to a DHCPOFFER
+ * message from a server, from a client verifying a previously allocated IP
+ * address or from a client extending the lease on a network address. If the
+ * DHCPREQUEST message contains a 'server identifier' option, the message is in
+ * response to a DHCPOFFER message. Otherwise, the message is a request to
+ * verify or extend an existing lease. If the client uses a 'client identifier'
+ * in a DHCPREQUEST message, it MUST use that same 'client identifier' in all
+ * subsequent messages. If the client included a list of requested parameters in
+ * a DHCPDISCOVER message, it MUST include that list in all subsequent messages.
+ *
+ * ...
+ *
+ * @throws  std::bad_alloc
+ */
+DhcpServerMessage *DHCPD::i_doRequest(DhcpClientMessage &req)
 {
     OptRequestedAddress reqAddr(req);
@@ -189,5 +323,5 @@
     {
         std::unique_ptr<DhcpServerMessage> nak (
-            createMessage(RTNET_DHCP_MT_NAC, req)
+            i_createMessage(RTNET_DHCP_MT_NAC, req)
         );
         nak->addOption(OptMessage("Requested address does not match ciaddr"));
@@ -199,14 +333,12 @@
     if (b == NULL)
     {
-        return createMessage(RTNET_DHCP_MT_NAC, req);
-    }
-
-
-    std::unique_ptr<DhcpServerMessage> ack (
-        createMessage(RTNET_DHCP_MT_ACK, req)
-    );
+        return i_createMessage(RTNET_DHCP_MT_NAC, req);
+    }
+
+
+    std::unique_ptr<DhcpServerMessage> ack(i_createMessage(RTNET_DHCP_MT_ACK, req));
 
     b->setState(Binding::ACKED);
-    saveLeases();
+    i_saveLeases();
 
     ack->setYiaddr(b->addr());
@@ -224,14 +356,16 @@
 
 
-/*
+/**
  * 4.3.5 DHCPINFORM message
  *
- *    The server responds to a DHCPINFORM message by sending a DHCPACK
- *    message directly to the address given in the 'ciaddr' field of the
- *    DHCPINFORM message.  The server MUST NOT send a lease expiration time
- *    to the client and SHOULD NOT fill in 'yiaddr'.  The server includes
- *    other parameters in the DHCPACK message as defined in section 4.3.1.
- */
-DhcpServerMessage *DHCPD::doInform(DhcpClientMessage &req)
+ * The server responds to a DHCPINFORM message by sending a DHCPACK message
+ * directly to the address given in the 'ciaddr' field of the DHCPINFORM
+ * message.  The server MUST NOT send a lease expiration time to the client and
+ * SHOULD NOT fill in 'yiaddr'.  The server includes other parameters in the
+ * DHCPACK message as defined in section 4.3.1.
+ *
+ * @throws  std::bad_alloc
+ */
+DhcpServerMessage *DHCPD::i_doInform(DhcpClientMessage &req)
 {
     if (req.ciaddr().u == 0)
@@ -247,10 +381,6 @@
         return NULL;
 
-    std::unique_ptr<DhcpServerMessage> ack (
-        createMessage(RTNET_DHCP_MT_ACK, req)
-    );
-
+    std::unique_ptr<DhcpServerMessage> ack(i_createMessage(RTNET_DHCP_MT_ACK, req));
     ack->addOptions(info);
-
     ack->maybeUnicast(req);
     return ack.release();
@@ -258,14 +388,15 @@
 
 
-/*
+/**
  * 4.3.3 DHCPDECLINE message
  *
- *    If the server receives a DHCPDECLINE message, the client has
- *    discovered through some other means that the suggested network
- *    address is already in use.  The server MUST mark the network address
- *    as not available and SHOULD notify the local system administrator of
- *    a possible configuration problem.
- */
-DhcpServerMessage *DHCPD::doDecline(DhcpClientMessage &req)
+ * If the server receives a DHCPDECLINE message, the client has discovered
+ * through some other means that the suggested network address is already in
+ * use.  The server MUST mark the network address as not available and SHOULD
+ * notify the local system administrator of a possible configuration problem.
+ *
+ * @throws  nothing
+ */
+DhcpServerMessage *DHCPD::i_doDecline(const DhcpClientMessage &req) RT_NOEXCEPT
 {
     RT_NOREF(req);
@@ -274,20 +405,22 @@
 
 
-/*
+/**
  * 4.3.4 DHCPRELEASE message
  *
- *    Upon receipt of a DHCPRELEASE message, the server marks the network
- *    address as not allocated.  The server SHOULD retain a record of the
- *    client's initialization parameters for possible reuse in response to
- *    subsequent requests from the client.
- */
-DhcpServerMessage *DHCPD::doRelease(DhcpClientMessage &req)
-{
-    if (req.ciaddr().u == 0)
-        return NULL;
-
-    bool released = m_db.releaseBinding(req);
-    if (released)
-        saveLeases();
+ * Upon receipt of a DHCPRELEASE message, the server marks the network address
+ * as not allocated.  The server SHOULD retain a record of the client's
+ * initialization parameters for possible reuse in response to subsequent
+ * requests from the client.
+ *
+ * @throws  nothing
+ */
+DhcpServerMessage *DHCPD::i_doRelease(const DhcpClientMessage &req) RT_NOEXCEPT
+{
+    if (req.ciaddr().u != 0)
+    {
+        bool fReleased = m_db.releaseBinding(req);
+        if (fReleased)
+            i_saveLeases();
+    }
 
     return NULL;
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DHCPD.h	(revision 79563)
@@ -29,37 +29,51 @@
 
 
+/**
+ * The core of the DHCP server.
+ *
+ * This class is feed DhcpClientMessages that VBoxNetDhcpd has picked up from
+ * the network.  After processing a message it returns the appropriate response
+ * (if any) which VBoxNetDhcpd sends out.
+ */
 class DHCPD
 {
-    const Config *m_pConfig;
-    RTCString m_strLeasesFileName;
-    Db m_db;
+    /** The DHCP configuration. */
+    const Config   *m_pConfig;
+    /** The lease database filename. */
+    RTCString       m_strLeasesFilename;
+    /** The lease database. */
+    Db              m_db;
 
 public:
     DHCPD();
 
-    int init(const Config *);
+    int init(const Config *) RT_NOEXCEPT;
 
-    DhcpServerMessage *process(const std::unique_ptr<DhcpClientMessage> &req)
+    DhcpServerMessage *process(const std::unique_ptr<DhcpClientMessage> &req) RT_NOEXCEPT
     {
-        if (req.get() == NULL)
-            return NULL;
-
-        return process(*req.get());
+        if (req.get() != NULL)
+            return process(*req.get());
+        return NULL;
     }
 
-    DhcpServerMessage *process(DhcpClientMessage &req);
+    DhcpServerMessage *process(DhcpClientMessage &req) RT_NOEXCEPT;
 
 private:
-    DhcpServerMessage *doDiscover(DhcpClientMessage &req);
-    DhcpServerMessage *doRequest(DhcpClientMessage &req);
-    DhcpServerMessage *doInform(DhcpClientMessage &req);
+    /** @name DHCP message processing methods
+     * @{ */
+    DhcpServerMessage *i_doDiscover(DhcpClientMessage &req);
+    DhcpServerMessage *i_doRequest(DhcpClientMessage &req);
+    DhcpServerMessage *i_doInform(DhcpClientMessage &req);
+    DhcpServerMessage *i_doDecline(const DhcpClientMessage &req) RT_NOEXCEPT;
+    DhcpServerMessage *i_doRelease(const DhcpClientMessage &req) RT_NOEXCEPT;
 
-    DhcpServerMessage *doDecline(DhcpClientMessage &req);
-    DhcpServerMessage *doRelease(DhcpClientMessage &req);
+    DhcpServerMessage *i_createMessage(int type, DhcpClientMessage &req);
+    /** @} */
 
-    DhcpServerMessage *createMessage(int type, DhcpClientMessage &req);
-
-    void loadLeases();
-    void saveLeases();
+    /** @name Lease database handling
+     * @{ */
+    int                i_loadLeases() RT_NOEXCEPT;
+    void               i_saveLeases() RT_NOEXCEPT;
+    /** @} */
 };
 
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp	(revision 79563)
@@ -36,5 +36,5 @@
  * Registers the ClientId format type callback ("%R[binding]").
  */
-void Binding::registerFormat()
+void Binding::registerFormat() RT_NOEXCEPT
 {
     if (!g_fFormatRegistered)
@@ -87,5 +87,5 @@
 }
 
-const char *Binding::stateName() const
+const char *Binding::stateName() const RT_NOEXCEPT
 {
     switch (m_state)
@@ -108,5 +108,5 @@
 
 
-Binding &Binding::setState(const char *pszStateName)
+Binding &Binding::setState(const char *pszStateName) RT_NOEXCEPT
 {
     if (strcmp(pszStateName, "free") == 0)
@@ -137,5 +137,5 @@
  * @param   tsDeadline          The expiry deadline to use.
  */
-bool Binding::expire(Timestamp tsDeadline)
+bool Binding::expire(Timestamp tsDeadline) RT_NOEXCEPT
 {
     if (m_state <= Binding::EXPIRED)
@@ -232,15 +232,23 @@
         /*
          * Decode from "de:ad:be:ef".
-         * XXX: RTStrConvertHexBytes() doesn't grok colons
          */
-        size_t cbBytes = strId.length() / 2;
-        uint8_t *pBytes = new uint8_t[cbBytes];
-        rc = RTStrConvertHexBytes(strId.c_str(), pBytes, cbBytes, 0);
+        /** @todo RTStrConvertHexBytes() doesn't grok colons */
+        size_t   cbBytes = strId.length() / 2;
+        uint8_t *pbBytes = new uint8_t[cbBytes];
+        rc = RTStrConvertHexBytes(strId.c_str(), pbBytes, cbBytes, 0);
         if (RT_SUCCESS(rc))
         {
-            std::vector<uint8_t> rawopt(pBytes, pBytes + cbBytes);
-            id = OptClientId(rawopt);
-        }
-        delete[] pBytes;
+            try
+            {
+                std::vector<uint8_t> rawopt(pbBytes, pbBytes + cbBytes);
+                id = OptClientId(rawopt);
+            }
+            catch (std::bad_alloc &)
+            {
+                delete[] pbBytes;
+                throw;
+            }
+        }
+        delete[] pbBytes;
     }
 
@@ -305,5 +313,5 @@
     }
     else
-    {   /* XXX: old code wrote timestamps instead of absolute time. */
+    {   /** @todo XXX: old code wrote timestamps instead of absolute time. */
         /* pretend that lease has just ended */
         Timestamp fakeIssued = Timestamp::now();
@@ -341,8 +349,5 @@
     m_pConfig = pConfig;
 
-    m_pool.init(pConfig->getIPv4PoolFirst(),
-                pConfig->getIPv4PoolLast());
-
-    return VINF_SUCCESS;
+    return m_pool.init(pConfig->getIPv4PoolFirst(), pConfig->getIPv4PoolLast());
 }
 
@@ -351,5 +356,5 @@
  * Expire old binding (leases).
  */
-void Db::expire()
+void Db::expire() RT_NOEXCEPT
 {
     const Timestamp now = Timestamp::now();
@@ -609,5 +614,5 @@
  * @param   pNewBinding     The new binding to add.
  */
-int Db::i_addBinding(Binding *pNewBinding)
+int Db::i_addBinding(Binding *pNewBinding) RT_NOEXCEPT
 {
     /*
@@ -662,5 +667,5 @@
  * @param   req                 The DHCP request.
  */
-void Db::cancelOffer(const DhcpClientMessage &req)
+void Db::cancelOffer(const DhcpClientMessage &req) RT_NOEXCEPT
 {
     const OptRequestedAddress reqAddr(req);
@@ -697,6 +702,7 @@
  * @param   req                 The DHCP request.
  * @returns true if found and released, otherwise false.
- */
-bool Db::releaseBinding(const DhcpClientMessage &req)
+ * @throws  nothing
+ */
+bool Db::releaseBinding(const DhcpClientMessage &req) RT_NOEXCEPT
 {
     const RTNETADDRIPV4 addr = req.ciaddr();
@@ -726,7 +732,14 @@
  * @param   strFilename         The file to write it to.
  */
-int Db::writeLeases(const RTCString &strFilename) const
+int Db::writeLeases(const RTCString &strFilename) const RT_NOEXCEPT
 {
     LogDHCP(("writing leases to %s\n", strFilename.c_str()));
+
+    /** @todo This could easily be written directly to the file w/o going thru
+     *        a xml::Document, xml::XmlFileWriter, hammering the heap and being
+     *        required to catch a lot of different exceptions at various points.
+     *        (RTStrmOpen, bunch of RTStrmPrintf using \%RMas and \%RMes.,
+     *        RTStrmClose closely followed by a couple of renames.)
+     */
 
     /*
@@ -789,6 +802,7 @@
  * @returns IPRT status code.
  * @param   strFilename         The file to load it from.
- */
-int Db::loadLeases(const RTCString &strFilename)
+ * @throws  nothing
+ */
+int Db::loadLeases(const RTCString &strFilename) RT_NOEXCEPT
 {
     LogDHCP(("loading leases from %s\n", strFilename.c_str()));
@@ -863,5 +877,5 @@
  * @return  IPRT status code.
  */
-int Db::i_loadLease(const xml::ElementNode *pElmLease)
+int Db::i_loadLease(const xml::ElementNode *pElmLease) RT_NOEXCEPT
 {
     Binding *pBinding = NULL;
@@ -878,5 +892,5 @@
         bool fExpired = pBinding->expire();
         if (!fExpired)
-            LogDHCP(("> LOAD: lease %R[binding]\n", pBinding));
+            LogDHCP(("> LOAD:         lease %R[binding]\n", pBinding));
         else
             LogDHCP(("> LOAD: EXPIRED lease %R[binding]\n", pBinding));
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Db.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Db.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Db.h	(revision 79563)
@@ -38,5 +38,7 @@
 
 /**
- * Address binding in the lease database.
+ * An address binding in the lease database.
+ *
+ * This is how an allocated IPv4 address is mananged.
  */
 class Binding
@@ -69,15 +71,15 @@
     /** @name Attribute accessors
      * @{ */
-    RTNETADDRIPV4   addr() const        { return m_addr; }
+    RTNETADDRIPV4   addr() const RT_NOEXCEPT        { return m_addr; }
 
-    const ClientId &id() const          { return m_id; }
+    const ClientId &id() const RT_NOEXCEPT          { return m_id; }
 
-    uint32_t        leaseTime() const   { return m_secLease; }
-    Timestamp       issued() const      { return m_issued; }
+    uint32_t        leaseTime() const RT_NOEXCEPT   { return m_secLease; }
+    Timestamp       issued() const RT_NOEXCEPT      { return m_issued; }
 
-    State           state() const       { return m_state; }
-    const char     *stateName() const;
-    Binding        &setState(const char *pszStateName);
-    Binding        &setState(State stateParam)
+    State           state() const RT_NOEXCEPT       { return m_state; }
+    const char     *stateName() const RT_NOEXCEPT;
+    Binding        &setState(const char *pszStateName) RT_NOEXCEPT;
+    Binding        &setState(State stateParam) RT_NOEXCEPT
     {
         m_state = stateParam;
@@ -87,5 +89,5 @@
 
 
-    Binding &setLeaseTime(uint32_t secLease)
+    Binding &setLeaseTime(uint32_t secLease) RT_NOEXCEPT
     {
         m_issued = Timestamp::now();
@@ -95,5 +97,5 @@
 
     /** Reassigns the binding to the given client.   */
-    Binding &giveTo(const ClientId &a_id)
+    Binding &giveTo(const ClientId &a_id) RT_NOEXCEPT
     {
         m_id = a_id;
@@ -108,6 +110,9 @@
     }
 
-    bool expire(Timestamp tsDeadline);
-    bool expire() { return expire(Timestamp::now()); }
+    bool expire(Timestamp tsDeadline) RT_NOEXCEPT;
+    bool expire() RT_NOEXCEPT
+    {
+        return expire(Timestamp::now());
+    }
 
     /** @name Serialization
@@ -119,5 +124,5 @@
     /** @name String formatting of %R[binding].
      * @{ */
-    static void registerFormat();
+    static void registerFormat() RT_NOEXCEPT;
 private:
     static DECLCALLBACK(size_t) rtStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType,
@@ -125,4 +130,6 @@
     static bool g_fFormatRegistered;
     /** @} */
+
+    Binding &operator=(const Binding &); /**< Shuts up warning C4626 (incorrect warning?). */
 };
 
@@ -130,4 +137,10 @@
 /**
  * The lease database.
+ *
+ * There is currently just one instance of this class in a running DHCP server
+ * residing in Dhcpd::m_db.  It covers one single range of IPv4 addresses, which
+ * currently unbound addressed are managed by m_pool.  The allocated addresses
+ * are kept in the m_bindings list.  Once an address has been allocated, it will
+ * stay in the m_bindings list even after released or expired.
  */
 class Db
@@ -151,20 +164,20 @@
 
     /** Check if @a addr belonges to this lease database. */
-    bool     addressBelongs(RTNETADDRIPV4 addr) const { return m_pool.contains(addr); }
+    bool     addressBelongs(RTNETADDRIPV4 addr) const RT_NOEXCEPT { return m_pool.contains(addr); }
 
     Binding *allocateBinding(const DhcpClientMessage &req);
-    bool     releaseBinding(const DhcpClientMessage &req);
+    bool     releaseBinding(const DhcpClientMessage &req) RT_NOEXCEPT;
 
-    void     cancelOffer(const DhcpClientMessage &req);
+    void     cancelOffer(const DhcpClientMessage &req) RT_NOEXCEPT;
 
-    void     expire();
+    void     expire() RT_NOEXCEPT;
 
     /** @name Database serialization methods
      * @{ */
-    int      loadLeases(const RTCString &strFilename);
+    int      loadLeases(const RTCString &strFilename) RT_NOEXCEPT;
 private:
-    int      i_loadLease(const xml::ElementNode *pElmLease);
+    int      i_loadLease(const xml::ElementNode *pElmLease) RT_NOEXCEPT;
 public:
-    int      writeLeases(const RTCString &strFilename) const;
+    int      writeLeases(const RTCString &strFilename) const RT_NOEXCEPT;
     /** @} */
 
@@ -176,5 +189,5 @@
 
     /* add binding e.g. from the leases file */
-    int      i_addBinding(Binding *pNewBinding);
+    int      i_addBinding(Binding *pNewBinding) RT_NOEXCEPT;
 };
 
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.cpp	(revision 79563)
@@ -289,6 +289,5 @@
 
     bool fHeader = true;
-    for (rawopts_t::const_iterator it = m_rawopts.begin();
-         it != m_rawopts.end(); ++it)
+    for (rawopts_t::const_iterator it = m_rawopts.begin(); it != m_rawopts.end(); ++it)
     {
         const uint8_t optcode = (*it).first;
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.h	(revision 79563)
@@ -69,5 +69,5 @@
     void setGiaddr(RTNETADDRIPV4 addr) { m_giaddr = addr; }
 
-    uint8_t messageType() const
+    uint8_t messageType() const RT_NOEXCEPT
     {
         Assert(m_optMessageType.present());
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h	(revision 79563)
@@ -55,6 +55,6 @@
 
   public:
-    uint8_t optcode() const { return m_OptCode; }
-    bool present() const { return m_fPresent; }
+    uint8_t optcode() const RT_NOEXCEPT { return m_OptCode; }
+    bool    present() const RT_NOEXCEPT { return m_fPresent; }
 
   public:
Index: /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.cpp	(revision 79563)
@@ -26,15 +26,22 @@
 
 
-int IPv4Pool::init(const IPv4Range &aRange)
+int IPv4Pool::init(const IPv4Range &aRange) RT_NOEXCEPT
 {
     AssertReturn(aRange.isValid(), VERR_INVALID_PARAMETER);
 
     m_range = aRange;
-    m_pool.insert(m_range);
+    try
+    {
+        m_pool.insert(m_range);
+    }
+    catch (std::bad_alloc &)
+    {
+        return VERR_NO_MEMORY;
+    }
     return VINF_SUCCESS;
 }
 
 
-int IPv4Pool::init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr)
+int IPv4Pool::init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT
 {
     return init(IPv4Range(aFirstAddr, aLastAddr));
@@ -48,5 +55,5 @@
  * @param   a_Range         The range to insert.
  */
-int IPv4Pool::i_insert(const IPv4Range &a_Range)
+int IPv4Pool::i_insert(const IPv4Range &a_Range) RT_NOEXCEPT
 {
     /*
@@ -86,5 +93,12 @@
      * No overlaps, insert it.
      */
-    m_pool.insert(itHint, a_Range);
+    try
+    {
+        m_pool.insert(itHint, a_Range);
+    }
+    catch (std::bad_alloc &)
+    {
+        return VERR_NO_MEMORY;
+    }
     return VINF_SUCCESS;
 }
@@ -114,5 +128,21 @@
             trimmed.FirstAddr += 1;
             m_pool.erase(itBeg);
-            m_pool.insert(trimmed);
+            try
+            {
+                m_pool.insert(trimmed);
+            }
+            catch (std::bad_alloc &)
+            {
+                /** @todo r=bird: Theortically the insert could fail with a bad_alloc and we'd
+                 * drop a range of IP address.  It would be nice if we could safely modify itBit
+                 * without having to re-insert it.  The author of this code (not bird) didn't
+                 * seem to think this safe?
+                 *
+                 * If we want to play safe and all that, just use a AVLRU32TREE (or AVLRU64TREE
+                 * if lazy) AVL tree from IPRT.  Since we know exactly how it's implemented and
+                 * works, there will be no uncertanties like this when using it (both here
+                 * and in the i_insert validation logic). */
+                LogRelFunc(("Caught bad_alloc! We're truely buggered now!\n"));
+            }
         }
     }
Index: /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/IPv4Pool.h	(revision 79563)
@@ -40,35 +40,35 @@
     IPV4HADDR LastAddr;        /**< Higest address (inclusive). */
 
-    IPv4Range()
+    IPv4Range() RT_NOEXCEPT
         : FirstAddr(0), LastAddr(0)
     {}
 
-    explicit IPv4Range(IPV4HADDR aSingleAddr)
+    explicit IPv4Range(IPV4HADDR aSingleAddr) RT_NOEXCEPT
         : FirstAddr(aSingleAddr), LastAddr(aSingleAddr)
     {}
 
-    IPv4Range(IPV4HADDR aFirstAddr, IPV4HADDR aLastAddr)
+    IPv4Range(IPV4HADDR aFirstAddr, IPV4HADDR aLastAddr) RT_NOEXCEPT
         : FirstAddr(aFirstAddr), LastAddr(aLastAddr)
     {}
 
-    explicit IPv4Range(RTNETADDRIPV4 aSingleAddr)
+    explicit IPv4Range(RTNETADDRIPV4 aSingleAddr) RT_NOEXCEPT
         : FirstAddr(RT_N2H_U32(aSingleAddr.u)), LastAddr(RT_N2H_U32(aSingleAddr.u))
     {}
 
-    IPv4Range(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr)
+    IPv4Range(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT
         : FirstAddr(RT_N2H_U32(aFirstAddr.u)), LastAddr(RT_N2H_U32(aLastAddr.u))
     {}
 
-    bool isValid() const
+    bool isValid() const RT_NOEXCEPT
     {
         return FirstAddr <= LastAddr;
     }
 
-    bool contains(IPV4HADDR addr) const
+    bool contains(IPV4HADDR addr) const RT_NOEXCEPT
     {
         return FirstAddr <= addr && addr <= LastAddr;
     }
 
-    bool contains(RTNETADDRIPV4 addr) const
+    bool contains(RTNETADDRIPV4 addr) const RT_NOEXCEPT
     {
         return contains(RT_N2H_U32(addr.u));
@@ -76,5 +76,5 @@
 
     /** Checks if this range includes the @a a_rRange. */
-    bool contains(const IPv4Range &a_rRange) const
+    bool contains(const IPv4Range &a_rRange) const RT_NOEXCEPT
     {
         return a_rRange.isValid()
@@ -85,5 +85,5 @@
 
 
-inline bool operator==(const IPv4Range &l, const IPv4Range &r)
+inline bool operator==(const IPv4Range &l, const IPv4Range &r) RT_NOEXCEPT
 {
     return l.FirstAddr == r.FirstAddr && l.LastAddr == r.LastAddr;
@@ -91,5 +91,5 @@
 
 
-inline bool operator<(const IPv4Range &l, const IPv4Range &r)
+inline bool operator<(const IPv4Range &l, const IPv4Range &r)  RT_NOEXCEPT
 {
     return l.LastAddr < r.FirstAddr;
@@ -118,6 +118,6 @@
     {}
 
-    int init(const IPv4Range &aRange);
-    int init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr);
+    int init(const IPv4Range &aRange) RT_NOEXCEPT;
+    int init(RTNETADDRIPV4 aFirstAddr, RTNETADDRIPV4 aLastAddr) RT_NOEXCEPT;
 
     RTNETADDRIPV4 allocate();
@@ -127,5 +127,5 @@
      * Checks if the pool range includes @a addr (allocation status not considered).
      */
-    bool contains(RTNETADDRIPV4 addr) const
+    bool contains(RTNETADDRIPV4 addr) const RT_NOEXCEPT
     {
         return m_range.contains(addr);
@@ -133,11 +133,11 @@
 
 private:
-    int i_insert(const IPv4Range &range);
+    int i_insert(const IPv4Range &range) RT_NOEXCEPT;
 #if 0
-    int i_insert(IPV4HADDR single)                            { return i_insert(IPv4Range(single)); }
+    int i_insert(IPV4HADDR single) RT_NOEXCEPT                          { return i_insert(IPv4Range(single)); }
 #endif
-    int i_insert(IPV4HADDR first, IPV4HADDR last)             { return i_insert(IPv4Range(first, last)); }
-    int i_insert(RTNETADDRIPV4 single)                        { return i_insert(IPv4Range(single)); }
-    int i_insert(RTNETADDRIPV4 first, RTNETADDRIPV4 last)     { return i_insert(IPv4Range(first, last)); }
+    int i_insert(IPV4HADDR first, IPV4HADDR last) RT_NOEXCEPT           { return i_insert(IPv4Range(first, last)); }
+    int i_insert(RTNETADDRIPV4 single) RT_NOEXCEPT                      { return i_insert(IPv4Range(single)); }
+    int i_insert(RTNETADDRIPV4 first, RTNETADDRIPV4 last) RT_NOEXCEPT   { return i_insert(IPv4Range(first, last)); }
 };
 
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.cpp	(revision 79563)
@@ -24,5 +24,5 @@
 
 
-size_t Timestamp::strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const
+size_t Timestamp::strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const RT_NOEXCEPT
 {
     RTTIMESPEC TimeSpec;
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.h	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Timestamp.h	(revision 79563)
@@ -39,10 +39,10 @@
 
 public:
-    Timestamp()
+    Timestamp() RT_NOEXCEPT
     {
         RTTimeSpecSetNano(&m_TimeSpec, 0);
     }
 
-    Timestamp(PCRTTIMESPEC a_pTimeSpec)
+    Timestamp(PCRTTIMESPEC a_pTimeSpec) RT_NOEXCEPT
     {
         m_TimeSpec = *a_pTimeSpec;
@@ -50,5 +50,5 @@
 
     /** Get a timestamp initialized to current time. */
-    static Timestamp now()
+    static Timestamp now() RT_NOEXCEPT
     {
         RTTIMESPEC Tmp;
@@ -57,5 +57,5 @@
 
     /** Get a timestamp with the given value in seconds since unix epoch. */
-    static Timestamp absSeconds(int64_t secTimestamp)
+    static Timestamp absSeconds(int64_t secTimestamp) RT_NOEXCEPT
     {
         RTTIMESPEC Tmp;
@@ -63,5 +63,5 @@
     }
 
-    Timestamp &addSeconds(int64_t cSecs)
+    Timestamp &addSeconds(int64_t cSecs) RT_NOEXCEPT
     {
         RTTimeSpecAddSeconds(&m_TimeSpec, cSecs);
@@ -69,5 +69,5 @@
     }
 
-    Timestamp &subSeconds(int64_t cSecs)
+    Timestamp &subSeconds(int64_t cSecs) RT_NOEXCEPT
     {
         RTTimeSpecSubSeconds(&m_TimeSpec, cSecs);
@@ -75,5 +75,5 @@
     }
 
-    RTTIMESPEC *getAbsTimeSpec(RTTIMESPEC *pTime) const
+    RTTIMESPEC *getAbsTimeSpec(RTTIMESPEC *pTime) const RT_NOEXCEPT
     {
         *pTime = m_TimeSpec;
@@ -81,5 +81,5 @@
     }
 
-    int64_t getAbsSeconds() const
+    int64_t getAbsSeconds() const RT_NOEXCEPT
     {
         return RTTimeSpecGetSeconds(&m_TimeSpec);
@@ -87,26 +87,26 @@
 
     /** Only for log formatting. */
-    size_t strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const;
+    size_t strFormatHelper(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput) const RT_NOEXCEPT;
 
-    int compare(const Timestamp &a_rRight) const
+    int compare(const Timestamp &a_rRight) const RT_NOEXCEPT
     {
         return RTTimeSpecCompare(&m_TimeSpec, &a_rRight.m_TimeSpec);
     }
 
-    friend bool operator<( const Timestamp &, const Timestamp &);
-    friend bool operator>( const Timestamp &, const Timestamp &);
-    friend bool operator==(const Timestamp &, const Timestamp &);
-    friend bool operator!=(const Timestamp &, const Timestamp &);
-    friend bool operator<=(const Timestamp &, const Timestamp &);
-    friend bool operator>=(const Timestamp &, const Timestamp &);
+    friend bool operator<( const Timestamp &, const Timestamp &) RT_NOEXCEPT;
+    friend bool operator>( const Timestamp &, const Timestamp &) RT_NOEXCEPT;
+    friend bool operator==(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
+    friend bool operator!=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
+    friend bool operator<=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
+    friend bool operator>=(const Timestamp &, const Timestamp &) RT_NOEXCEPT;
 };
 
 
-inline bool operator<( const Timestamp &l, const Timestamp &r) { return l.compare(r) < 0; }
-inline bool operator>( const Timestamp &l, const Timestamp &r) { return l.compare(r) > 0; }
-inline bool operator==(const Timestamp &l, const Timestamp &r) { return l.compare(r) == 0; }
-inline bool operator!=(const Timestamp &l, const Timestamp &r) { return l.compare(r) != 0; }
-inline bool operator<=(const Timestamp &l, const Timestamp &r) { return l.compare(r) <= 0; }
-inline bool operator>=(const Timestamp &l, const Timestamp &r) { return l.compare(r) >= 0; }
+inline bool operator<( const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) < 0; }
+inline bool operator>( const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) > 0; }
+inline bool operator==(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) == 0; }
+inline bool operator!=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) != 0; }
+inline bool operator<=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) <= 0; }
+inline bool operator>=(const Timestamp &l, const Timestamp &r) RT_NOEXCEPT { return l.compare(r) >= 0; }
 
 #endif /* !VBOX_INCLUDED_SRC_Dhcpd_Timestamp_h */
Index: /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp	(revision 79562)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp	(revision 79563)
@@ -372,17 +372,16 @@
     {
         int rc = ifWait();
-
-        if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
-            continue;
-
+        if (   rc != VERR_INTERRUPTED
 #if 0 /* we wait indefinitely */
-        if (rc == VERR_TIMEOUT)
-            ...;
+            && rc != VERR_TIMEOUT
 #endif
-
-        if (RT_FAILURE(rc))
+            )
+            ifProcessInput();
+        else
+        {
+            LogRel(("ifWait failed: %Rrc\n", rc));
+            RTMsgError("ifWait failed: %Rrc", rc);
             return;
-
-        ifProcessInput();
+        }
     }
 }
@@ -613,9 +612,14 @@
 int VBoxNetDhcpd::main(int argc, char **argv)
 {
-    int rc;
-
+    /*
+     * Register string format types.
+     */
     ClientId::registerFormat();
-
-    /* XXX: We no longer need hardcoded and compat methods. We should remove them soon. */
+    Binding::registerFormat();
+
+    /*
+     * Parse the command line into a configuration object.
+     */
+    /** @todo XXX: We no longer need hardcoded and compat methods. We should remove them soon. */
     if (argc < 2)
         m_Config = Config::hardcoded();
@@ -624,25 +628,47 @@
         m_Config = Config::create(argc, argv);
     else
-        m_Config = Config::compat(argc, argv);
-
+    {
+        try
+        {
+            m_Config = Config::compat(argc, argv);
+        }
+        catch (std::bad_alloc &)
+        {
+            m_Config = NULL;
+            RTMsgError("Out of memory");
+            return VERR_NO_MEMORY;
+        }
+    }
     if (m_Config == NULL)
         return VERR_GENERAL_FAILURE;
 
-    rc = m_server.init(m_Config);
-
-    /* connect to the intnet */
-    rc = ifInit(m_Config->getNetwork(),
-                m_Config->getTrunk(),
-                m_Config->getTrunkType());
-    if (RT_FAILURE(rc))
-        return rc;
-
-    /* setup lwip */
-    rc = vboxLwipCoreInitialize(lwipInitCB, this);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    ifPump();
-    return VINF_SUCCESS;
+    /*
+     * Initialize the server.
+     */
+    int rc = m_server.init(m_Config);
+    if (RT_SUCCESS(rc))
+    {
+        /* connect to the intnet */
+        rc = ifInit(m_Config->getNetwork(), m_Config->getTrunk(), m_Config->getTrunkType());
+        if (RT_SUCCESS(rc))
+        {
+            /* setup lwip */
+            rc = vboxLwipCoreInitialize(lwipInitCB, this);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * Pump packets more or less for ever.
+                 */
+                ifPump();
+            }
+            else
+                RTMsgError("Terminating - vboxLwipCoreInitialize failed: %Rrc", rc);
+        }
+        else
+            RTMsgError("Terminating - ifInit failed: %Rrc", rc);
+    }
+    else
+        RTMsgError("Terminating - Dhcpd::init failed: %Rrc", rc);
+    return rc;
 }
 
@@ -707,7 +733,4 @@
                              ip_addr_t *addr, u16_t port)
 {
-    err_t error;
-    int rc;
-
     RT_NOREF(pcb, addr, port);
 
@@ -735,5 +758,5 @@
 
     octets_t data;
-    rc = msgOut->encode(data);
+    int rc = msgOut->encode(data);
     if (RT_FAILURE(rc))
         return;
@@ -743,5 +766,5 @@
         return;
 
-    error = pbuf_take(q.get(), &data.front(), (u16_t)data.size());
+    err_t error = pbuf_take(q.get(), &data.front(), (u16_t)data.size());
     if (error != ERR_OK)
         return;
