root 6 ماه پیش
والد
کامیت
3b9d55aff4
2فایلهای تغییر یافته به همراه29 افزوده شده و 4 حذف شده
  1. 10 1
      core/cluster_manager.py
  2. 19 3
      core/dns_manager.py

+ 10 - 1
core/cluster_manager.py

@@ -22,17 +22,26 @@ def broadcast_to_cluster(action, domain):
                 headers = {"X-API-Key": node['api_key'], "Content-Type": "application/json"}
                 payload = {"domain": domain, "masters": masters}
                 
+                # BUG FIX: Ασφαλής Opener για να μην κόβεται από Proxies / SSL
+                proxy_handler = urllib.request.ProxyHandler({})
+                https_handler = urllib.request.HTTPSHandler(context=config.ssl_ctx)
+                opener = urllib.request.build_opener(proxy_handler, https_handler)
+                
                 if action == 'add_slave':
                     req = urllib.request.Request(url, data=json.dumps(payload).encode('utf-8'), headers=headers, method='POST')
                 elif action == 'delete_zone':
                     req = urllib.request.Request(f"{url}/{domain}", headers=headers, method='DELETE')
                 
-                urllib.request.urlopen(req, timeout=5, context=config.ssl_ctx)
+                opener.open(req, timeout=10)
+                print(f"Cluster Sync OK: {node['name']} ({action} {domain})")
             except Exception as e:
                 print(f"Cluster Sync FAIL: {node['name']} -> {e}")
                 
     import threading
     threading.Thread(target=task, daemon=True).start()
+                
+    import threading
+    threading.Thread(target=task, daemon=True).start()
 
 def broadcast_adblock_to_cluster(action):
     def task():

+ 19 - 3
core/dns_manager.py

@@ -69,7 +69,21 @@ def sanitize_record_name(name, domain):
 def get_zone_block(conf, domain):
     parts = conf.split('zone "')
     for p in parts[1:]:
-        if p.startswith(domain + '"'): return 'zone "' + p
+        if p.startswith(domain + '"'):
+            block = 'zone "' + p
+            open_braces = 0
+            in_block = False
+            # Μετράμε αγκύλια για να βρούμε το τέλος της ζώνης με ακρίβεια
+            for i, char in enumerate(block):
+                if char == '{': 
+                    open_braces += 1
+                    in_block = True
+                elif char == '}': 
+                    open_braces -= 1
+                    if in_block and open_braces == 0:
+                        if i + 1 < len(block) and block[i+1] == ';': return block[:i+2]
+                        return block[:i+1]
+            return block
     return None
 
 def get_zone_file_path(domain):
@@ -144,6 +158,8 @@ def get_zone_masters_list(domain):
     if not block: return []
     if "type slave" in block or "type forward" in block:
         import re
-        m = re.search(r'(?:masters|forwarders)\s*\{\s*([^;\}]+);', block, re.S | re.I)
-        if m: return [ip.strip() for ip in m.group(1).split(';') if ip.strip()]
+        m = re.search(r'(?:masters|forwarders)\s*\{\s*(.*?)\s*\};', block, re.S | re.I)
+        if m:
+            ips_raw = m.group(1).replace('\n', ' ')
+            return [ip.strip() for ip in ips_raw.split(';') if ip.strip()]
     return []