2

DNSがどのように機能するかについての論文を書き、Pythonで小さいながらも機能するDNSサーバーを構築する必要があります。

私は次のようにパケットが受信されたときにスレッドを開く単純なUDPソケットサーバーを持っています:

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)

ハンドラー関数は、メモリ内で要求されたレコードを見つけようとするだけで、見つからない場合は、別のサーバーでDNSクエリを実行する別の関数を実行して、レコードがない場合はレコードをフェッチします。これはややフェイルセーフであり、私の問題はどこにありますか。

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)

ご覧のとおり、まだ完成していませんが、すでに問題があります。場合によっては、この関数が渡され、エラーログにエラーが発生しない限りスレッドが終了しないことがあります。私はテストしましたが、エラーログには子がスローしたすべてのエラーが記録されているはずです。私は、設定された時間ごとに一連のプリセットからランダムな要求を送信するようにプログラムされた単純なクライアントを持っていますが、子供がハングするときのパターンはないようです。約24時間のテストの後、約1〜3個のゾンビスレッドが残ります。

疑問に思っている場合は、これが例外関数のようになります。

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
4

1 に答える 1

2

これはプロトコルの正確な仕様であるため、RFCを確認します。DNSの問題は、RFCが複数あることです。簡単なスタートとして、基本が含まれているRFC1035を確認します。高度な機能が必要な場合は、他の関連するRFCを確認してください。

于 2012-10-04T13:42:28.350 に答える