commit d1ff79f3355b55498b55b08b2d6bec5dbd69e82e
parent 81683c98e459b37667fb94231ff8daa250047530
Author: rexxnor <rexxnor+gnunet@brief.li>
Date: Thu, 27 Sep 2018 22:05:29 +0200
added incremental zone transfer logic
Diffstat:
1 file changed, 50 insertions(+), 18 deletions(-)
diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py
@@ -16,6 +16,8 @@ Options:
"""
# imports
+import sys
+import time
import subprocess
import csv
import dns.query
@@ -53,12 +55,13 @@ class GNSMigrator():
master_answer = dns.resolver.query(soa_answer[0].mname, 'A')
try:
- zone = dns.zone.from_xfr(dns.query.xfr(master_answer[0].address, domain))
+ zone = dns.zone.from_xfr(dns.query.xfr(
+ master_answer[0].address, domain))
except dns.resolver.NoAnswer:
- print("the domain '%s' did not answer our xfr request" % domain)
+ print("nameserver for '%s' did not answer" % domain)
continue
except dns.exception.FormError:
- print("the domain '%s' does not allow xfr requests from your ip" % domain)
+ print("domain '%s' does not allow xfr requests" % domain)
continue
cls.zones[domain] = (zone, (master_answer[0].address, domain))
@@ -72,13 +75,16 @@ class GNSMigrator():
# building list with arguments
reverse_parsing = domain.split('.')[::-1]
for domainpart in reverse_parsing:
- pkey_lookup = subprocess.Popen([GNUNET_ZONE_CREATION_COMMAND, '-d'],
+ pkey_lookup = subprocess.Popen([GNUNET_ZONE_CREATION_COMMAND,
+ '-d'],
stdout=subprocess.PIPE)
pkey_line = subprocess.Popen(['grep', domainpart],
stdin=pkey_lookup.stdout,
stdout=subprocess.PIPE)
- pkey_zone = subprocess.check_output(['cut', '-d', ' ', '-f3'],
- stdin=pkey_line.stdout).decode().strip()
+ pkey_zone = subprocess.check_output(['cut', '-d',
+ ' ', '-f3'],
+ stdin=pkey_line.stdout)
+ pkey_zone = pkey_zone.decode().strip()
pkey_lookup.stdout.close()
pkey_line.stdout.close()
# Create identity in GNUnet
@@ -86,22 +92,26 @@ class GNSMigrator():
subprocess.run([GNUNET_ZONE_CREATION_COMMAND,
'-C', domainpart])
- pkey_lookup = subprocess.Popen([GNUNET_ZONE_CREATION_COMMAND, '-d'],
+ pkey_lookup = subprocess.Popen([GNUNET_ZONE_CREATION_COMMAND,
+ '-d'],
stdout=subprocess.PIPE)
pkey_line = subprocess.Popen(['grep', domainpart],
stdin=pkey_lookup.stdout,
stdout=subprocess.PIPE)
- pkey_zone = subprocess.check_output(['cut', '-d', ' ', '-f3'],
- stdin=pkey_line.stdout).decode().strip()
+ pkey_zone = subprocess.check_output(['cut', '-d',
+ ' ', '-f3'],
+ stdin=pkey_line.stdout)
+ pkey_zone = pkey_zone.decode().strip()
pkey_lookup.stdout.close()
pkey_line.stdout.close()
- # If it is TLD, don't add PKEY to higher zone as they do not exist
+ # If it is TLD, don't add PKEY to higher zone
if counter > 0:
result = subprocess.check_output([GNUNET_GNS_COMMAND,
'-t', 'PKEY',
'-u', '%s.%s' %
- (domainpart, reverse_parsing[counter - 1])])
+ (domainpart,
+ reverse_parsing[counter - 1])])
if "No results." in result.decode():
subprocess.run([GNUNET_NAMESTORE_COMMAND,
@@ -115,7 +125,7 @@ class GNSMigrator():
@staticmethod
def add_records_to_gns(zonename, zone, domain, dnsresolver):
"""
- Checks if records are present
+ Checks if records are present and adds them if not
:param zonename: zonename of zone to add records to
:param zone: the transfered zone
:param domain: full domain of zone
@@ -186,6 +196,31 @@ class GNSMigrator():
"""
return domain.split('.')[0]
+ @classmethod
+ def refresh_zone(cls, domain, zonetuple, dnsresolver):
+ """
+ Refresh the zone using IXFR and the previous serial as reference
+
+ Returns 0 on unchanged and 1 on changed
+
+ :param domain: The domain to transfer and migrate
+ :param zonetuple: The necessary data tuple for the transfer
+ :param dnsresolver: Optional user specified resolver for subdomains
+ """
+ zone, xfrinfo = zonetuple
+ zonename = cls.get_lowest_domain_part(domain)
+ cls.add_records_to_gns(zonename, zone, domain, dnsresolver)
+
+ # Ugly way to get serial
+ serial = int(str(zone.get_rdataset('@', dns.rdatatype.SOA)).split(' ')[5])
+ newzone = dns.zone.from_xfr(dns.query.xfr(xfrinfo[0],
+ xfrinfo[1],
+ rdtype=dns.rdatatype.IXFR,
+ serial=serial))
+ if newzone == zone:
+ return 1
+ return 0
+
def main():
"""
@@ -202,7 +237,7 @@ def main():
print('Exiting...')
return 1
- dnsresolver = args['<resolver>']
+ dnsresolver = args.get('<resolver>', None)
domainlist = []
@@ -225,11 +260,8 @@ def main():
gnsmigrator.initial_zone_transfer()
for domain, zonetuple in gnsmigrator.zones.items():
- zone, xfrinfo = zonetuple
- zonename = gnsmigrator.get_lowest_domain_part(domain)
- gnsmigrator.add_records_to_gns(zonename, zone, domain, dnsresolver)
- # retain the information needed for a second zone transfer
- #print(xfrinfo)
+ # Returns a value 0 if not changed and 1 if changed
+ gnsmigrator.refresh_zone(domain, zonetuple, dnsresolver)
if __name__ == '__main__':
main()