2010-10-04 8 views
2

J'ai écrit du code qui interroge les adns. Le problème avec ce code est qu'il est bloqué, comment? Permettez-moi de l'expliquer:Python et ADNS, tombant en boucle infinie quelque part

  • Dis mon dnslist est [ "8.8.4.4", "8.8.8.8", "208.67.220.220", "208.67.222.222", "192.168.50.1"]
  • Il ferait apparaître un DNS de la liste et la requête contre elle, maintenant cela signifie que DNS sera interrogé dans l'ordre inverse
  • Peu importe ce que je fais, Il ne montre jamais les résultats de la DNS il ramassé en premier (dans notre cas 192.168.50.1
  • Je n'étais pas sûr si ce DNS jamais répondu ainsi
    • D'abord j'ai changé la liste DNS pour contenir seulement ce dernier serveur DNS et la morue e exécute bien
    • Deuxièmement j'ai utilisé l'ancienne liste avec 5 serveurs DNS sauf que le dernier était géré par mon afin que je puisse suivre si le code l'interroge même ou pas, et à ma grande surprise la requête a lieu. Donc, une requête est faite, nous obtenons un résultat mais ce résultat n'est jamais inséré dans resolve_hosts pour une raison quelconque, et comme ce résultat n'est pas inséré, sa longueur restera inférieure à la longueur de dnslist, provoquant une boucle infinie.

Que pensez-vous pourrait être la cause de ce problème et comment le résoudre?

exécution de code Résultats

Inside class's init' 
Data 
host www.yahoo.com 
dnslist length 5 
intensity 1 
Inside resolve() 
inside finished_resolving() 
Resolved : 0/5 
Inside 'while not finished_resolving' 
Queue: 0/1 
Launching Querying for www.yahoo.com/1 on 192.168.50.1 
Queue: 1/1 
Launching Querying for www.yahoo.com/1 on 208.67.222.222 
inside collect_results() 
inside finished_resolving() 
Resolved : 0/5 
Inside 'while not finished_resolving' 
------------------------ CLIPPED ---------------- 
Inside 'while not finished_resolving' 
inside collect_results() 
Inside collect_results's for query in self.adns.completed() 
DNS used was208.67.222.222 
Answered : (0, 'any-fp.wa1.b.yahoo.com', 1286169807, ('69.147.125.65', '67.195.160.76')) 
Resolved www.yahoo.com to 69.147.125.65 using 208.67.222.222 
Resolved hosts count1 
And they are: 
{'208.67.222.222': '69.147.125.65'} 


inside finished_resolving() 
Resolved : 1/5 
Inside 'while not finished_resolving' 
Queue: 1/1 
Launching Querying for www.yahoo.com/1 on 208.67.220.220 
inside collect_results() 
inside finished_resolving() 
Resolved : 1/5 
Inside 'while not finished_resolving' 
-------------------------- CLIPPED -------------------- 
inside collect_results() 
Inside collect_results's for query in self.adns.completed() 
DNS used was208.67.220.220 
Answered : (0, 'any-fp.wa1.b.yahoo.com', 1286169790, ('67.195.160.76', '69.147.125.65')) 
Resolved www.yahoo.com to 67.195.160.76 using 208.67.220.220 
Resolved hosts count2 
And they are: 
{'208.67.222.222': '69.147.125.65', '208.67.220.220': '67.195.160.76'} 


inside finished_resolving() 
Resolved : 2/5 
Inside 'while not finished_resolving' 
Queue: 1/1 
Launching Querying for www.yahoo.com/1 on 8.8.8.8 
inside collect_results() 
inside finished_resolving() 
Resolved : 2/5 
Inside 'while not finished_resolving' 
-------------------------- CLIPPED -------------------- 
inside collect_results() 
Inside collect_results's for query in self.adns.completed() 
DNS used was8.8.8.8 
Answered : (0, 'eu-fp.wa1.b.yahoo.com', 1286169758, ('87.248.122.122',)) 
Resolved www.yahoo.com to 87.248.122.122 using 8.8.8.8 
Resolved hosts count3 
And they are: 
{'208.67.222.222': '69.147.125.65', '208.67.220.220': '67.195.160.76', '8.8.8.8': '87.248.122.122'} 


inside finished_resolving() 
Resolved : 3/5 
Inside 'while not finished_resolving' 
Queue: 1/1 
Launching Querying for www.yahoo.com/1 on 8.8.4.4 
inside collect_results() 
inside finished_resolving() 
Resolved : 3/5 
Inside 'while not finished_resolving' 
-------------------- CLIPPED ------------------------------------- 
inside collect_results() 
Inside collect_results's for query in self.adns.completed() 
DNS used was8.8.4.4 
Answered : (0, 'eu-fp.wa1.b.yahoo.com', 1286169757, ('87.248.122.122',)) 
Resolved www.yahoo.com to 87.248.122.122 using 8.8.4.4 
Resolved hosts count4 
And they are: 
{'208.67.222.222': '69.147.125.65', '208.67.220.220': '67.195.160.76', '8.8.8.8': '87.248.122.122', '8.8.4.4': '87.248.122.122'} 


inside finished_resolving() 
Resolved : 4/5 
Inside 'while not finished_resolving' 
inside collect_results() 
inside finished_resolving() 
Resolved : 4/5 
---------------- CLIPPED ------------------------------- 

(dernier bloc ne cesse de répéter jusqu'à ce que le système commence à se raccrocher, la charge va jusqu'à 24)

code

test.py

import adns 
from time import time 
from async_dns import AsyncResolver 



dnslist2 = ["8.8.4.4", "8.8.8.8", "208.67.220.220", "208.67.222.222", "192.168.50.1"] #192.168.50.1 is a dns server i manage 
host = "www.yahoo.com" 
record = adns.rr.A 
intensity = len(dnslist2)/5+1 

ar = AsyncResolver(dnslist2, host, record, intensity) 
start = time() 
resolved = ar.resolve() 
end = time() 

print "\n\n" 

for dns, ip in resolved.items(): 
    if ip is None: 
    print "%s could not resolv %s." % (dns, host) 
    else: 
    print "%s resolved it to %s : %s" % (dns, host, ip) 

print "\n\n----------------------------------------------------" 
print "It took %.2f seconds to query %d dns." % (end-start, len(dnslist)) 
print "----------------------------------------------------" 

async _dns.py

#!/usr/bin/python 
# 

import sys 
import adns 
from time import time 

class AsyncResolver(object): 
    def __init__(self, dnslist, host, record, intensity=10): 

     """ 
     dnslist: a list of dns used to resolve 
     host : hostname to resolve 
     record: recordtype to resolve 
     intensity: how many hosts to resolve at once 
     """ 
     print "Inside class's init'" 
     self.dnslist = dnslist 
     self.host = host 
     self.record = record 


     if intensity >= len(dnslist) : 
      self.intensity = len(dnslist)/5+1 
     else: 
      self.intensity = intensity 

     print "Data" 
     print "host " + host 
     print "dnslist length " + str(len(dnslist)) 
     print "intensity " + str(intensity) 




    def resolve(self): 
     """ Resolves hosts and returns a dictionary of { 'dns': 'ip' }. """ 
     print "Inside resolve()" 

     host = self.host 
     record = self.record 
     resolved_hosts = {} 
     active_queries = {} 
     dns_queue = self.dnslist[:] 

     def collect_results(): 
      print "inside collect_results()" 
      for query in self.adns.completed(): 
       print "Inside collect_results's for query in self.adns.completed()" 
       answer = query.check() 
       dns = active_queries[query] 
       print "DNS used was" + dns 
       print "Answered : " + str(answer) 
       del active_queries[query] 
       if answer[0] == 0: 
        #print "Inside answer[0] == 0 , ip:" + answer[3][0] 
        ip = answer[3][0] 
        resolved_hosts[dns] = ip 
        print "Resolved %s to %s using %s" % (host, ip, dns) 
        print "Resolved hosts count" + str(len(resolved_hosts)) 
        print "And they are: " 
        print str(resolved_hosts) 
        print "\n" 

       elif answer[0] == 101 and not record == adns.rr.CNAME: # CNAME if CNAME wasn't required' 
        print "ooopppps, i got a CNAME, gotta find its A" 
        print "\n" 
        query = self.adns.submit(answer[1], adns.rr.A) 
        active_queries[query] = dns 
       else: 
        resolved_hosts[dns] = None 
        print "THIS COULD NOT BE RESOLVED" 

     def finished_resolving(): 
      print "inside finished_resolving()" 
      print "Resolved : " + str(len(resolved_hosts)) + "/" + str(len(self.dnslist)) 
      return len(resolved_hosts) == len(self.dnslist) 

     while not finished_resolving(): 
      print "Inside 'while not finished_resolving'" 
      while dns_queue and len(active_queries) <= self.intensity: 
       print "Queue: " + str(len(active_queries)) + "/" + str(self.intensity) 
       dns = dns_queue.pop() 
       self.adns = adns.init(adns.iflags.noautosys,sys.stderr,"nameserver "+dns) 
       query = self.adns.submit(host, record) 
       print "Launching Querying for " + host + "/" + str(record) + " on " + dns 
       active_queries[query] = dns 
      collect_results() 
     return resolved_hosts 

Répondre

0

Votre boucle while not finished_resolving() sera évidemment continuer aussi longtemps que finished_resolving() retourne Vrai. Cette fonction compare simplement len(resolved_hosts) et len(self.dnslist). Cependant, autant que je peux voir vous ne changez jamais la longueur de l'une ou l'autre de ces variables à l'intérieur de la boucle, donc cela continuera pour toujours.

Éditer après commentaire Il n'y a rien dans ces deux blocs qui affecte la longueur de l'une ou l'autre des deux variables. S'il vous plaît expliquer comment vous pensez qu'ils sont en train d'être changés.

+0

non, mauvaise hypothèse. Voir collect_results()? et tandis que dns_queue et len ​​(active_queries) <= self.intensity? – Shoaibi

+0

resolved_hosts [dns] = ip à l'intérieur du premier if inside collect_results, ceci si évalue à vrai si l'enregistrement a été résolu en enregistrement "A". – Shoaibi

1

Je viens d'essayer d'utiliser la liaison adns python et j'ai rencontré un problème similaire - le tableau de requêtes terminé n'est jamais complètement rempli, provoquant l'exécution indéfinie de la boucle de contrôle. Dans mon cas, il est apparu que les domaines qui ne pouvaient pas être résolus (à cause de NXDOMAIN etc) n'étaient jamais ajoutés au tableau des requêtes terminées (avec une valeur vide/nulle)

Je regardais la liaison C mais je ne pouvais pas voir une structure de données distincte pour contenir les résultats ayant échoué, il semble donc que ceux-ci devraient être ajoutés aux requêtes 'terminées' d'une manière ou d'une autre. Je suspecte qu'il y ait un bogue dans la bibliothèque de liaison ou d'adns empêchant ceci de se produire.