From 25fc01f04f4cbf164e91afc95bec6921e9464c29 Mon Sep 17 00:00:00 2001 From: Ferenc Schulcz <schulcz.ferenc@gmail.com> Date: Thu, 6 Feb 2025 15:11:23 +0100 Subject: [PATCH] Multiple DNS server support --- dyndns.py | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/dyndns.py b/dyndns.py index 393b46a..a1d4c82 100644 --- a/dyndns.py +++ b/dyndns.py @@ -1,11 +1,12 @@ import services import db import os -import requests import datetime import config import random import hashlib +import asyncio +import aiohttp from werkzeug.security import check_password_hash @@ -36,6 +37,19 @@ def dyndns(**kwargs): return rqtools.render_template(plugin_dir + '/templates/dyndns.html', records=ownRecords, recordsCount=recordsCount, otherRecords=otherRecords) +async def sendRequest(session, url, urlparams): + try: + async with session.get(url, params=urlparams) as response: + return response.status + except Exception as e: + print(f"Could not reach {url}: {e}") + return 600 + +async def sendAllRequests(urls, urlparams): + async with aiohttp.ClientSession() as session: + requests = [sendRequest(session, url, urlparams) for url in urls] + return await asyncio.gather(*requests) + def dyndnsRegister(**kwargs): session = kwargs['session'] request = kwargs['request'] @@ -52,14 +66,23 @@ def dyndnsRegister(**kwargs): return rqtools.redirect(rqtools.url_for('service', servicename='dyndns')) tokenseed = str(random.randint(1, 2**32)) + str(random.randint(1, 2**32)) domain = request.form['domainname'] - r = requests.get(url = config.get('DYNDNS_SERVER_URL') + '/register', params = {'domain': domain, 'tokenseed': tokenseed}) - reply = r.json() - if r.status_code > 299: - db.sendMessage(session['username'], reply['message']) + registrationStatuses = asyncio.run(sendAllRequests(config.get('DYNDNS_SERVER_URLS'), {'domain': domain, 'tokenseed': tokenseed})) + allFail = True + allSuccess = True + for s in registrationStatuses: + if s > 299: + allSuccess = False + else: + allFail = False + if allFail: + db.sendMessage(session['username'], "Registration is not possible as no DNS servers are online.") return rqtools.redirect(rqtools.url_for('service', servicename='dyndns')) token = hashlib.md5((domain + tokenseed).encode()).hexdigest() - x = db.db['dyndns-records'].insert_one({'username': session['username'], 'domain': reply['domainName'], 'token': token, 'ip': "null", 'lastupdate': "never"}) - db.sendMessage(session['username'], reply['message']) + x = db.db['dyndns-records'].insert_one({'username': session['username'], 'domain': domain + '.dyndns.sfsrv.hu', 'token': token, 'ip': "null", 'lastupdate': "never"}) + if allSuccess: + db.sendMessage(session['username'], "Registration successful. Record is not served until first DNS update.") + else: + db.sendMessage(session['username'], "Registration successful although not all DNS servers are online. Record is not served until first DNS update.") return rqtools.redirect(rqtools.url_for('service', servicename='dyndns')) @@ -74,12 +97,21 @@ def dyndnsUpdate(**kwargs): x = db.db['dyndns-records'].find_one({'token': request.args['token']}) if x['ip'] == ip: return {'message': 'Already set.'}, 200 - r = requests.get(url = config.get('DYNDNS_SERVER_URL')+ "/update", params = {'token': request.args['token'], 'ip': ip}) - reply = r.json() - if r.status_code < 300: + updateStatuses = asyncio.run(sendAllRequests(config.get('DYNDNS_SERVER_URLS'), {'token': request.args['token'], 'ip': ip})) + allFail = True + allSuccess = True + for s in updateStatuses: + if s > 299: + allSuccess = False + else: + allFail = False + if allSuccess: + print("Not updated " + x['domain'] + " as no DNS servers are online.") + return {'message': 'NOT updated. No DNS servers are online.'}, 500 + else: print("Updated " + x['domain'] + " from " + x['ip'] + " to " + ip) db.db['dyndns-records'].update_one(filter={'token': request.args['token']}, update={'$set': {'ip': ip, 'lastupdate': datetime.datetime.now()}}) - return reply, r.status_code + return {'message': 'Updated.'}, 200 def dyndnsList(**kwargs): -- GitLab