private bool SyncToInternextX() { bool result = false; imscpDomain.UpdateCache(); imscpDomainDns.UpdateCache(); imscpSubdomain.UpdateCache(); imscpAdmins.UpdateCache(); foreach (Domain imscpDomain in imscpDomain.GetStructs()) { if (imscpDomain.Name.Split('.').Length > 2) { this.LogDebug("Ignore sub domain {0}", imscpDomain); continue; } this.LogDebug("Check domain <cyan>{0}", imscpDomain); bool changeInProgress = imscpDomain.Status != "ok"; //check if the imscp domain is present at internet x if (!autodnsCache.TryGetValue(imscpDomain.Name, out AutodnsRecordItem item)) { //already sent email ? if (warningsSent.Contains(imscpDomain.Name)) { continue; } //no, maybe someone repaired it ? bool found = false; if (DateTime.Now > autodnsRecheckTime) { SyncFromInternetX(); found = autodnsCache.TryGetValue(imscpDomain.Name, out item); } if (!found) { //no its really missing this.LogWarning("Zone <red>{0}<default> is not present at <red>InternetX<default>, skipping...", imscpDomain); warningsSent.Include(imscpDomain.Name); //send email try { var email = imscpAdmins[imscpDomain.AdminID].Email; m_SmtpClient.Send(m_MailSender, email, "CaveSystems AutoDNS", string.Format("Zone {0} is registered at imscp but is not present at InternetX.\nPlease correct this error...", imscpDomain)); } catch { } continue; } } Autodns autodns = item.Autodns; Set <DnsResourceRecord> records = new Set <DnsResourceRecord>(item.Records); List <DnsResourceRecord> newRecords = new List <DnsResourceRecord>(); var imscpDomainDnsEntries = imscpDomainDns.GetStructs(nameof(DomainDns.DomainID), (int)imscpDomain.ID); foreach (DomainDns imscpDomainDnsEntry in imscpDomainDnsEntries) { if (imscpDomainDnsEntry.Status == "todelete") { continue; } if (imscpDomainDnsEntry.Status.StartsWith("to")) { changeInProgress = true; this.LogDebug("Domain <cyan>{0}<default> change in progress <yellow>{1}", imscpDomain, imscpDomainDnsEntry.Status); break; } if (imscpDomainDnsEntry.Status != "ok") { changeInProgress = true; this.LogWarning("Domain <cyan>{0}<default> error <red>{1}", imscpDomain, imscpDomainDnsEntry.Status); break; } DnsResourceRecord newRec = new DnsResourceRecord { Name = imscpDomainDnsEntry.Name.Replace("wildcard", "*") }; if (imscpDomainDnsEntry.Name.StartsWith(".") || (imscpDomainDnsEntry.Name != imscpDomain.Name + "." && !imscpDomainDnsEntry.Name.EndsWith("." + imscpDomain.Name + "."))) { this.LogWarning("Invalid entry <yellow>{0}", imscpDomainDnsEntry); ImscpDeleteDomainDns(imscpDomainDnsEntry); continue; } newRec.Name = newRec.Name.Substring(0, newRec.Name.Length - imscpDomain.Name.Length - 1).TrimEnd('.'); if (newRec.Name.Length == 0) { newRec.Name = null; } newRec.TTL = imscpDomainDnsEntry.TTL; newRec.Type = imscpDomainDnsEntry.DomainType; if (newRec.Name == "www") { this.LogWarning("Invalid entry <yellow>{0}", imscpDomain); ImscpDeleteDomainDns(imscpDomainDnsEntry); continue; } try { switch (imscpDomainDnsEntry.DomainType) { default: newRec.Value = imscpDomainDnsEntry.DomainText; break; case "MX": case "SRV": int i = imscpDomainDnsEntry.DomainText.IndexOf(' '); newRec.Pref = uint.Parse(imscpDomainDnsEntry.DomainText.Substring(0, i)); newRec.Value = imscpDomainDnsEntry.DomainText.Substring(i + 1); break; } } catch (Exception ex) { this.LogWarning(ex, "Invalid entry <yellow>{0}", imscpDomainDnsEntry); ImscpDeleteDomainDns(imscpDomainDnsEntry); continue; } newRecords.Add(newRec); } if (changeInProgress) { result = true; continue; } //add autoconfig if not present if (!newRecords.Any(r => r.Name == "autoconfig")) { newRecords.Insert(0, new DnsResourceRecord() { Name = "autoconfig", Type = "CNAME", Value = imscpConfig.Hostname + ".", TTL = 360, }); } //add www if not present if (!newRecords.Any(r => r.Name == "www")) { newRecords.Insert(0, new DnsResourceRecord() { Name = "www", Type = "A", Value = imscpConfig.DomainIP.ToString(), TTL = 360, }); } //add mx if not present if (!newRecords.Any(r => r.Type == "MX")) { newRecords.Insert(0, new DnsResourceRecord() { Name = "", Type = "MX", Value = imscpConfig.Hostname + ".", TTL = 360, Pref = 10, }); } //add TXT spf if not present if (!newRecords.Any(r => r.Type == "TXT" && r.Value.StartsWith("v=spf1"))) { newRecords.Add(new DnsResourceRecord() { Name = "", Type = "TXT", Value = $"v=spf1 a mx ip4:{imscpConfig.DomainIP}/32", TTL = 360, }); } //check subdomains foreach (var sub in imscpSubdomain.GetStructs(nameof(Subdomain.DomainID), imscpDomain.ID)) { var items = newRecords.FindAll(r => r.Name == sub.Name); if (items.Count != 1 || items[0].Type != "A") { foreach (var i in items) { newRecords.Remove(i); } newRecords.Add(new DnsResourceRecord() { Name = sub.Name, Type = "A", Value = imscpConfig.DomainIP.ToString(), TTL = 360, }); } } bool update = false; if (newRecords.Count == records.Count) { foreach (DnsResourceRecord rec in newRecords) { if (records.Contains(rec)) { records.Remove(rec); } else { break; } } update = records.Count > 0; } else { update = true; } if (update) { result = true; this.LogInfo("Update <magenta>{0}<default> with <cyan>{1}<default> resource records.", imscpDomain, newRecords.Count); autodns.ZoneUpdate(imscpDomain.Name, imscpConfig.DomainIP, newRecords); //update at internet x SyncFromInternetX(autodns.ZoneInquire(imscpDomain.Name)); } } return(result); }
public AutodnsRecordItem(Autodns a, string zone, DnsResourceRecord[] records) { Autodns = a; Zone = zone; Records = records; }