(Only the first step is followed in the 0.2.00 release)

In order to look up an arbitrary domain query, we do the following:

1. We take the question (questions?) out of the query, extracting the 
   domain name followed by the 2-byte query class.  

2. This binary string (example.com. is stored as
   "\007example\003com\000" instead of "example.com.") is looked up on the
   hash.

3. If we find the string, give the resolver querying us the answer
   to the query.  The answer will be: AN: N records (the answers) NS:
   the NS records for this zone (unless it is a NS query) AR: If the
   answers are NS or MX records, the corresponding A records (but
   only if we have them).

4. If we do not find the string, change the query type to a CNAME request
   and try again. 

5. If we find an appropriate CNAME record, return the CNAME record
   (optionally: the record the CNAME points to) in the AN section.  
   in the NS section, we include the NS records for the authoritative 
   nameservers that returned the CNAME record (unless we did the optional
   thing, at which point we return the NS records to what the CNAME points
   to).  In the AR section, we return the IPs of the NS records (and the
   IP if needed for the optional thing if we did the optional thing.
   MaraDNS 1.0 is not going to do the optional thing.)

6. If we do not find the CNAME record, try a NS request.  

7. If the NS request succeeds, return nothing in the AN section. Since we
   are this far along in the algorithm, we can safely assume that this is
   not handled by us, and is handled by another name server.  Tell them
   that name server: Nothing in AN, the appropriate name servers in NS,
   and the "glue" IPs to those name servers in AR.

8. OK, if the NS record does not succeed, perhaps someone sent us
   a request for "\004name\003sub\007example\003com\000" where 
   "\003sub\007example\003com\000" is a NS record pointing to the
   nameserver that resolves name.sub.exmaple.com.  To cover this 
   case, we need to go up the tree label by label, until we find
   A NS record, which we may or may not be us.  So, we need
   to look for NSs for sub.example.com., if that fails, look for
   NSes for example.com., then finally look for NSes for com.
   (We could be the dot in .com)  If we do not find any NS entries,
   then this is a query which we need to (when supported) recursively
   query.  If we find a NS record and it is not us, return that NS record.
   If we find an NS query and it is us, we go on to step 9.

9. OK, now we need to look for a '*' record with the same type as the
   request, e.g. "_\007example\003com\000" (_ is 0x5F, which is not a legal
   length for a domain label, nor is it used by any EDNS label, and I will
   eventually get around to writing a draft that the EDNS label 0x5f should
   be used as a "private" namespace (akin to using 0x7fXXXXXX for localhost
   lookups))

10. If we find this record, return the answer, as detailed in step 3.

11. Maybe they have a '*' record which is a CNAME (ugh).  Look for
    a star record with the same name and is a CNAME.  If it is found,
    then return the CNAME information, as described in step 5.

12. There could be a NS record which handles all of these labels (this
    can be useful if you have two differnet nameservers handling domains
    for a domain.  If our nameserver does not handle the name in
    question, maybe nameserver 2 handles the name).  Return the answer,
    as described in step 7.

13. OK, there is no star record for this label.  Perhaps there is a
    star record for something up the tree.  Go up the tree, as described 
    in step 8.  Check for a star record as described in steps 10-12.  
    
14. OK, no star record found, so NS record found.  It's a NXDOMAIN.  
    Give them a NXDOMAIN reply, with the NS for the zone (see step 8
    for a general idea of how to get this info).

Once we find a domain query, we do the following:

1. We Point to the first reply.  Each domain reply has the following
   information:

   a) The raw binary reply for this domain, in a js_string object
      (unit_size is 1, rdlength is unit_length, and the data is the
       string).

   b) A pointer to the IP for this domain, for MX and NS records
  
   c) A pointer to the next domain we want (either another record for
      the same query, _or_ a pointer to the first NS record, or to null
      if we are at the last NS record)

2. This reply becomes the first AN record (unless we find out that a
   different name server really handles this reply, at which point we
   tell them nothing in the AN section).  We then do the following:
  
   If the IP points to something, look at that and add the data to the 
   AR section.  

   If the "next" points to something, look at that and add the data to the
   AN section (unless the "next" points to a NS and the query was not for
   a NS, at which point we add the DATA to the NS section)
  
   Hack:  There is no need to distinguish the AN section from the NS
          section.  We just have to keep track of how many ANs and NSs
          there are.  (Well, OK, we need to distinguish if we want to
	  do round-robin rotation correctly)

   Do this until the "next" points to NULL.

3. Form a header, concatenate the AN+NS string, concatenate the AR string
   string, compress the whole string, and send the string back to the
   user.

In order to populate the hash when reading the zone files, we will perform
a two-pass algorithm:

1. for key in csv1.keys():

	The zone name is the key, the file location is csv[key]

	Open up the file, remembering the zone name.

	Get the SOA, make the data RFC1035 binary data, and put it in
	the hash

	Get all of the NS records.  If a hash element for the RFC1035
        domain-name+2-byte class already exists, add this data to the
        end of the "chain" of domain names.

	Get all of the other records.  Add the NS records to the end
        of all newly created elements, place an "overlapping" record in
        the "chain" of domain names between the last non-NS and the first
	NS record.

2. At this point, we will have the IPs of all our records that have IP
   records in the database.  Go through all of the elements in the 
   big hash:

	If the record is a MX or NS record, look at the contents of
	the record.  If we know the IP for the record contents, we point
 	to that IP.



	
