dns - TXT records in dnsPython -


i have implemented simple dns server. responds txt record. hosting script ns server example.com. ns server x.y.z.k. works fine when issue like:

$ dig demo.example.com @x.y.z.k

; <<>> dig 9.3.6-p1-redhat-9.3.6-4.p1.el5_4.1 <<>> demo.example.com @x.y.z.k ;; global options:  printcmd ;; got answer: ;; ->>header<<- opcode: query, status: noerror, id: 10028 ;; flags: qr rd ra; query: 1, answer: 1, authority: 2, additional: 2  ;; question section: ;demo.example.com. in  ;; answer section: demo.example.com. 1000 in txt "test message" 

but not work when ask same question 1 of public name servers (for example sun's dns @ 4.2.2.1):

$ dig demo.example.com @4.2.2.1 (i same thing when issue $ dig demo.example.com @4.2.2.1 txt)

; <<>> dig 9.3.6-p1-redhat-9.3.6-4.p1.el5_4.1 <<>> demo.example.com ;; global options:  printcmd ;; got answer: ;; ->>header<<- opcode: query, status: servfail, id: 10905 ;; flags: qr rd ra; query: 1, answer: 0, authority: 0, additional: 0  ;; question section: ;demo.example.com. in  ;; query time: 5837 msec ;; server: 172.16.1.1#53(172.16.1.1) ;; when: tue jul 20 04:01:27 2010 ;; msg size  rcvd: 75 

do guys have idea wrong? interestingly if change response type cname, instead of txt, works fine.

def dns_respond(resp, q, data_type):     rrset = dns.rrset.from_text(q.name, 1000,            dns.rdataclass.in, dns.rdatatype.txt, 'test message')     resp.answer.append(rrset)     return resp  def dns_ok(resp, q, data = none, msg = ''):     return dns_respond(resp = resp, q = q, data_type = 'ok')  def dns_error(resp, q):     return dns_respond(resp = resp, q = q, data_type = 'error')  def requesthandler(address, message):     resp = none     message_id = ord(message[0]) * 256 + ord(message[1])     logging.debug('msg id = ' + str(message_id))     if message_id in serving_ids:         # request taken, drop message         logging.debug('i serving request.')         return     serving_ids.append(message_id)     msg = dns.message.from_wire(message)     op = msg.opcode()     if op == 0:         # standard , inverse query         qs = msg.question         if len(qs) > 0:             q = qs[0]             logging.debug('request ' + str(q))             if q.rdtype == dns.rdatatype.a:                 resp = std_qry(msg)             else:                 # not implemented                 #resp = std_qry(msg)                 resp = make_response(qry=msg, rcode=4)        else:         # not implemented         resp = make_response(qry=msg, rcode=4)         if resp:         s.sendto(resp.to_wire(), address)  def std_qry(msg):     qs = msg.question     logging.debug(str(len(qs)) + ' questions.')      answers = []     nxdomain = false     q in qs:         resp = make_response(qry=msg)         logging.critical('sending...')         return dns_ok(resp, q)  def make_response(qry=none, id=none, rcode=0):     if qry none , id none:         raise exception, 'bad use of make_response'     if qry none:         resp = dns.message.message(id)         # qr = 1         resp.flags |= dns.flags.qr         if rcode != 1:             raise exception, 'bad use of make_response'     else:         resp = dns.message.make_response(qry)     #resp.flags |= dns.flags.aa     resp.flags |= dns.flags.ra     resp.set_rcode(rcode)     return resp s = socket.socket(socket.af_inet, socket.sock_dgram) s.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) s.bind(('', 53)) logging.debug('binded udp port 53.') serving_ids = []  while true:     logging.debug('waiting requests.')     message, address = s.recvfrom(1024)     logging.debug('serving request.')     requesthandler(address, message) 

i can see few real bugs that'll stop working:

  1. you're returning txt record a record query - show stopper.
  2. you should returning aa flag (authoritative answer) instead of ra
  3. your headers there 2 answers in authority , additional sections, there aren't
  4. you're not removing served ids list once they've been served

in addition there few protocol-related issues need fixing:

  1. you need able return ns records , soa records when asked, or delegation may not work reliably
  2. query matching should use whole (source ip, source port, queryid) tuple account, not (queryid)
  3. if question name in right domain, not right subdomain should return nxdomain (rcode = 3)
  4. if question name matches right subdomain wrong record type should return noerror (rcode = 0) instead of notimpl
  5. if question name isn't part of right domain @ should return refused (rcode = 5)

Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -