DNS Projects HTTP Projects OSS Projects Mono Projects Testing DNS Servers Main Page





Four Calorie Servers/DNS v2 - Development pages


The diagram (Dia 1.0) shown below reveals part of a rough draft of the new server. Obviously, many of the DomAns subclasses are left unshown for the sake of brevity.


Dia 1.0

Click for additional information: Process Diagram


The hierarchy representation, a simpleton "fixed" affair built into the query manager of the original (Four Calorie Servers v1) version, will now be rolled into a collection of objects.

Class List:

TFiveCalorieDNS
- Top level class used to instantiate all server objects.

THttpThreads
- Collection object for http server threads used for DNS monitoring function

TThreadedQueryManager
- Maintains list of controlled domains. Finds match between requested domain (query)
and active domain object, and allows resolution to continue on a thread.


TDomains
- Collection object for DNS "Domains"

TDomain
- Domain object that contains TDomAns derived classes

TDomAnsTXT, TDomAnsNS, TDomAnsSOA, TDomAnsAddrRec, TDomAnsPTR, TDomAnsMX, TDomAnsHINFO, etc
- Subclasses for TDomAns superclass.

TLog
- Retrieves statistical data for admin's browser display

TSynchronizedConfiguration
- This associated class is used to roll domain hierarchy data into and out of
storage, and optionally, to maintain synchronization with other servers.


The diagram (Dia 2.0, below) shows the "hierarchy loop" for the domain collection(s)


Dia 2.0



Other RR (resource records)

The original (Four Calorie Servers v1) version of the DNS server could handle only A, NS, SOA, MX, and PTR RR types, and could recognize A6/AAAA RR types well enough to allow for graceful fallback to IPv4. However; there are other RR types and TXT RR subtypes that are interesting and useful. Some of these additional types will be included in the new server:

Nice to have:

Obsoleted:

There are many RR types that are security related:
- TKEY, TSIG, TA, KX, DS, IPSECKEY, RRSIG, etc

Some RR types are communication protocol specific:
- X25, ISDN, ATMA, etc



Other pertinent information:

Response codes are not uniformly utilized by internet DNS servers. While there is an explicit code for a non-existent domain (3), many DNS servers return ServFail (2) instead. Similarly, many servers return the ServFail code in place of the "Not implemented" code (4).

Response Codes:

Domain Classes:

The age of the internet means that older domain classes and RR types have been left scattered around even when better ones have been created. This "record bloat" means that many RR types are not much used or not used at all, but are included for backward compatibility. In the following chart, only class 1 (IN) is of much importance, and is the only one that will be incorporated within the new server, and the reason that the domain class is not subclassed:




Why write another DNS server?

One reason is purely personal. This author regularly sets up a large variety of operating systems, and in the course of this work, very often has a need for a compact, reliable, and easy-to-configure DNS server. Additionally, a requirement that this author holds himself bound to is the stipulation that each server intallation must be jailed, chrooted, or otherwise isolated. While most DNS servers can be isolated in one of the aforementioned ways, and some even have installation scripts that "do it for you", at the end of the day it is far easier (and gives better piece of mind) to be able to drop a single application file into a chroot directory, along with perhaps a C/C++ library file or two, and be done with it.

A secondary reason also has to do with security issues. Many DNS servers have, over the years been "enhanced" with tons of additional features. Security is inversely proportional to the number of links in the chain. No matter that the chainsmiths are excellent, professional, and above reproach (may even infallible), the corallary still holds sway in the real world. Any feature that I don't need, but nonetheless resides within the executable, is just an un-necessary risk and I don't want to be exposed to it.

- RL Scheckelhoff



Copyright 2007 - Datazygte, Inc.

sigs: dia 1: 024744e8de0628a086fd056af85411f7
sigs: dia 2: 259af57bdf53684b923bef264988dc99





 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */


 /*
   * File: t-domains.cpp
   * 
   * Purpose: some basic domain building blocks for fivecdns-1.0.0
   *          including perpetually indexed list for domain searches

   * License: (BSD-like license)
   * Copyright (c) 2004, 2005, 2006, 2007, 2008 Datazygte, Inc
   * Contributors: ron scheckelhoff
   *      
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY WARRANTIES  
   * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
   
   * IN NO EVENT SHALL THE AUTHOR(s) BE LIABLE FOR ANY DIRECT, INDIRECT, 
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
   * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   * 
 */


#include "t-domains.hpp"


// Constants ...
const int DOMAIN_NAME_MIN_LENGTH = 3;
const int DOMAIN_NAME_MAX_LENGTH = 64;


//
// Construct
//

TDomains::TDomains()
{

        // tbe
        
}


//
// Destruct
//

TDomains::~TDomains()
{

        // tbe
        
}



//
// Add a domain to domains 
//
TDomain* TDomains::Add(TDomain* objdm_ParentDomain, char* pstrDomainText)
{        
        try
        {
                TFcsError* obj_FcsErr = new TFcsError();                                                                                                  
                TDomain* objdm_NewDomain = NULL;                
        
                if (objdm_ParentDomain != NULL)
                {
                        if (pstrDomainText != NULL)                
                        {                
                                if ((strlen(pstrDomainText) >=  DOMAIN_NAME_MIN_LENGTH) &&
                                        (strlen(pstrDomainText) < DOMAIN_NAME_MAX_LENGTH))
                                {
                                        
                                        if (objdm_ParentDomain->objdm_Stem == NULL)
                                        {
                                                // No stem yet, so make it
                                                objdm_ParentDomain->objdm_Stem = new TDomain(pstrDomainText);
                                        
                                                if (objdm_ParentDomain->objdm_Stem != NULL)
                                                    objdm_NewDomain = objdm_ParentDomain->objdm_Stem;                        
                                                else
                                                    throw(obj_FcsErr->ErrInfo(ERR_CREATE_DOMAIN, GetMsg(ERR_CREATE_DOMAIN), "TDomains::Add", true));                                                                                                                            
                                        }
                                        else
                                        {
                                                // Stem already exists, so insert new leaf
                                                objdm_NewDomain = new TDomain(pstrDomainText);                        
                                        
                                                if (objdm_NewDomain != NULL)
                                                {
                                                    objdm_NewDomain->objdm_Parent = objdm_ParentDomain;  
                                                    objdm_NewDomain = Insert(objdm_NewDomain);
                                                }
                                                else
                                                    throw(obj_FcsErr->ErrInfo(ERR_CREATE_DOMAIN,
                                                        GetMsg(ERR_CREATE_DOMAIN), "TDomains::Add", true)); }                                                                                                                                                                                                                                    
                                }
                              else
                                   throw(obj_FcsErr->ErrInfo(ERR_DOMAIN_NAME_LENGTH,
                                   GetMsg(ERR_DOMAIN_NAME_LENGTH), "TDomains::Add", true));                                                                            
                        }
                        else
                             throw(obj_FcsErr->ErrInfo(ERR_DOMAIN_TEXT_NULL,
                             GetMsg(ERR_DOMAIN_TEXT_NULL), "TDomains::Add", true));                                            
                }
                else
                    throw(obj_FcsErr->ErrInfo(ERR_PARENT_DOMAIN_NULL,
                    GetMsg(ERR_PARENT_DOMAIN_NULL), "TDomains::Add", true));                                            

                
                delete obj_FcsErr;                             
                return (objdm_NewDomain);                                        

                
        }
        catch (TFcsError* obj_FcsErr)
        {
               if (obj_FcsErr->blnRethrow)
                {
                        obj_FcsErr->blnRethrow = false;                        
                        throw (obj_FcsErr);
                }
                else
                        delete (obj_FcsErr);
        }
                
}



//
// Insert a new Domain leaf
//
//

TDomain* TDomains::Insert(TDomain* objdm_New)
{

        try
        {
                TFcsError* obj_FcsErr = new TFcsError();                                                                                                  
        
                TLeafInfo* obj_LeafInfo;
                TDomain* objdm_Ins = objdm_New;
        
                if (objdm_Ins != NULL)
                {
                        if (this->objdm_Stem != NULL)
                        {
                                obj_LeafInfo = IndexKeySearch(objdm_Ins);
                        
                                if (obj_LeafInfo->NoError)
                                {
                                    // KeySearch was able to find appropriate insert points
                                    objdm_Ins->objdm_HighLeaf = obj_LeafInfo->objdm_HighLeaf;
                                    objdm_Ins->objdm_LowLeaf = obj_LeafInfo->objdm_LowLeaf;
                                }
                                else
                                {
                                        objdm_Ins = NULL;

                                       throw(obj_FcsErr->ErrInfo(ERR_INSERT_DOMAIN, GetMsg(ERR_INSERT_DOMAIN), "TDomains::Insert", true));                                            
                                }
                                
                        }
                        else
                        {
                                // Tried to insert, but no stem yet, so add as stem
                                this->objdm_Stem = objdm_Ins;
                        }
                }
                else
                      throw(obj_FcsErr->ErrInfo(ERR_DOMAIN_NULL, GetMsg(ERR_DOMAIN_NULL), "TDomains::Insert", true));                                            

                
                delete obj_FcsErr;
                return objdm_Ins;

                
        }
        catch (TFcsError* obj_FcsErr)
        {
                if (obj_FcsErr->blnRethrow)
                {                        
                        throw (obj_FcsErr);
                }
                else
                        delete (obj_FcsErr);
        }
        
}