Commit c7feb361 authored by Petr Špaček's avatar Petr Špaček

msgdiff: add proper command-line interface and help texts

Configuration options are read from file respdiff.cfg.
See file example.
parent dd633ec6
......@@ -17,6 +17,11 @@ def ipaddr_check(addr):
dns.inet.af_for_address(addr) # raises ValueError if the address is bogus
return addr
def comma_list(lstr):
Split string 'a, b' into list [a, b]
return [name.strip() for name in lstr.split(',')]
# declarative config format description for always-present sections
# dict structure: dict[section name][key name] = type
......@@ -26,10 +31,11 @@ _CFGFMT = {
'jobs': int,
'servers': {
'names': lambda s: [n.strip() for n in s.split(',')]
'names': comma_list
'diff': {
'target': str,
'criteria': comma_list,
#!/usr/bin/env python3
import argparse
import logging
import itertools
import multiprocessing
import multiprocessing.pool as pool
......@@ -9,6 +13,7 @@ import dns.message
import dns.exception
import lmdb
import cfg
import dbhelper
......@@ -202,7 +207,8 @@ def compare(answers, criteria, target):
return (others_agree, target_diffs)
def worker_init(criteria_arg, target_arg):
def worker_init(envdir_arg, criteria_arg, target_arg):
global envdir
global criteria
global target
......@@ -211,7 +217,7 @@ def worker_init(criteria_arg, target_arg):
global diffs_db
config = dbhelper.env_open.copy()
'path': sys.argv[1],
'path': envdir_arg,
'readonly': False,
'create': False,
'writemap': True,
......@@ -223,6 +229,7 @@ def worker_init(criteria_arg, target_arg):
criteria = criteria_arg
target = target_arg
envdir = envdir_arg
def compare_lmdb_wrapper(qid):
......@@ -240,19 +247,31 @@ def compare_lmdb_wrapper(qid):
def main():
target = 'kresd'
ccriteria = ['opcode', 'rcode', 'flags', 'question', 'qname', 'qtype', 'answertypes', 'answerrrsigs'] #'authority', 'additional', 'edns']
#ccriteria = ['opcode', 'rcode', 'flags', 'question', 'qname', 'qtype', 'answer', 'authority', 'additional', 'edns', 'nsid']
config = dbhelper.env_open.copy()
'path': sys.argv[1],
logging.basicConfig(format='%(levelname)s %(message)s', level=logging.DEBUG)
parser = argparse.ArgumentParser(
description='compute diff from answers stored in LMDB and write diffs to LMDB')
parser.add_argument('-c', '--config', default='respdiff.cfg', dest='cfgpath',
help='config file (default: respdiff.cfg)')
parser.add_argument('envdir', type=str,
help='LMDB environment to read answers from and to write diffs to')
args = parser.parse_args()
config = cfg.read_cfg(args.cfgpath)
envconfig = dbhelper.env_open.copy()
'path': args.envdir,
'readonly': False,
'create': False
lenv = lmdb.Environment(**config)
lenv = lmdb.Environment(**envconfig)
db = lenv.open_db(key=dbhelper.ANSWERS_DB_NAME, create=False, **dbhelper.db_open)
except lmdb.NotFoundError:
logging.critical('LMDB does not contain DNS answers in DB %s, terminating.',
db = lenv.open_db(key=dbhelper.ANSWERS_DB_NAME, create=False, **dbhelper.db_open)
try: # drop diffs DB if it exists, it can be re-generated at will
diffs_db = lenv.open_db(key=dbhelper.DIFFS_DB_NAME, create=False, **dbhelper.db_open)
with lenv.begin(write=True) as txn:
......@@ -263,7 +282,7 @@ def main():
qid_stream = dbhelper.key_stream(lenv, db)
with pool.Pool(
initargs=(ccriteria, target)
initargs=(args.envdir, config['diff']['criteria'], config['diff']['target'])
) as p:
for i in p.imap_unordered(compare_lmdb_wrapper, qid_stream, chunksize=10):
......@@ -25,5 +25,9 @@ port = 53535
# symbolic name of server under test
target = kresd
# other servers are used as reference when comparing answers from the target
target = kresd
# fields and comparison methods used when comparing two DNS messages
criteria = opcode, rcode, flags, question, qname, qtype, answertypes, answerrrsigs
# other supported criteria values: authority, additional, edns, nsid
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment