title: DNS server client communication protocol
body: <p>I need to write a paper on how DNS works and build a small but functional DNS server in python.</p>
  
  <p>I have a simple UDP socket server that opens a thread when a packet is received like this:</p>
  
  <pre><code>while 1:
    try:
      stream, addr = serversocket.recvfrom(buffr)
      threading.Thread(target=handler, args=(stream, addr, threading.activeCount(),)).start()
    except:
      exc_type, exc_value, exc_traceback = sys.exc_info()
      except_catch(exc_type.__name__, exc_value, exc_traceback, threading.current_thread().name)
  </code></pre>
  
  <p>The handler function simply tries to find the record requested in memory and if it does not it will execute another function that runs a dns query on another server to fetch the record if he does not have it. This is somewhat of a fail-safe and where my problem is.</p>
  
  <pre><code>def dnsrn(ip, type):
    try:
      mkr = dns.resolver.Resolver()
      mkr.nameservers = ['192.168.0.1']
      res = mkr.query(ip, type)
  
      for rdata in res:
        return rdata.address # this works for A records
        # to do for other types of records
  
    except:
      exc_type, exc_value, exc_traceback = sys.exc_info()
      except_catch(exc_type.__name__, exc_value, exc_traceback, threading.current_thread().name)
  </code></pre>
  
  <p><strong>I have not yet finished it as you can see but I already have a problem.
  Sometimes, this function will hand and the thread will never finish without it giving any error what so ever in the error log.
  I have tested and the error log should capture all errors thrown by the child.
  I have a simple client that is programmed to send a random request out a lit of presets every set time and there seems to be no pattern to  when the child hangs.
  After about 24 hours of testing I'm left with about 1-3 zombie threads.</strong></p>
  
  <p>In case you are wondering this is what the exception function looks like:</p>
  
  <pre><code>def except_catch(type, value, track, thread=None):
    if type != "SystemExit":
      import traceback
  
      rawreport = traceback.format_exception(type, value, track)
      report = "\n" . join(rawreport)
  
      errorlog = open(error_log_path + "/errors.log", "a")
  
      if thread != None:
        errorlog.write("Exception in thread: " + thread + "\n\n")
  
      errorlog.write(("%s\n" + "-" * 30 + "\n\n") % report)
  
      errorlog.close()
  sys.excepthook = except_catch
  </code></pre>