mirror of
https://github.com/fosrl/olm.git
synced 2026-10-21 03:59:15 +02:00
Merge pull request #126 from fosrl/dev
Handle remove on a per site level correctly
This commit is contained in:
@@ -755,6 +755,12 @@ func (p *DNSProxy) RemoveDNSRecord(domain string, ip net.IP) {
|
|||||||
p.recordStore.RemoveRecord(domain, ip)
|
p.recordStore.RemoveRecord(domain, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDNSRecordForSite removes DNS records for a domain that are owned by a specific site.
|
||||||
|
// If ip is nil, removes all records for the domain that are owned by that site.
|
||||||
|
func (p *DNSProxy) RemoveDNSRecordForSite(domain string, ip net.IP, siteId int) {
|
||||||
|
p.recordStore.RemoveRecordForSite(domain, ip, siteId)
|
||||||
|
}
|
||||||
|
|
||||||
// GetDNSRecords returns all IP addresses for a domain and record type.
|
// GetDNSRecords returns all IP addresses for a domain and record type.
|
||||||
// The second return value indicates whether the domain exists.
|
// The second return value indicates whether the domain exists.
|
||||||
func (p *DNSProxy) GetDNSRecords(domain string, recordType RecordType) ([]net.IP, bool) {
|
func (p *DNSProxy) GetDNSRecords(domain string, recordType RecordType) ([]net.IP, bool) {
|
||||||
|
|||||||
+73
-2
@@ -23,6 +23,7 @@ type recordSet struct {
|
|||||||
A []net.IP
|
A []net.IP
|
||||||
AAAA []net.IP
|
AAAA []net.IP
|
||||||
SiteId int
|
SiteId int
|
||||||
|
owners map[string]map[int]bool // IP string -> owning site IDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSRecordStore manages local DNS records for A, AAAA, and PTR queries.
|
// DNSRecordStore manages local DNS records for A, AAAA, and PTR queries.
|
||||||
@@ -71,9 +72,17 @@ func (s *DNSRecordStore) AddRecord(domain string, ip net.IP, siteId int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if m[domain] == nil {
|
if m[domain] == nil {
|
||||||
m[domain] = &recordSet{SiteId: siteId}
|
m[domain] = &recordSet{SiteId: siteId, owners: make(map[string]map[int]bool)}
|
||||||
}
|
}
|
||||||
rs := m[domain]
|
rs := m[domain]
|
||||||
|
if rs.owners == nil {
|
||||||
|
rs.owners = make(map[string]map[int]bool)
|
||||||
|
}
|
||||||
|
ipKey := ip.String()
|
||||||
|
if rs.owners[ipKey] == nil {
|
||||||
|
rs.owners[ipKey] = make(map[int]bool)
|
||||||
|
}
|
||||||
|
rs.owners[ipKey][siteId] = true
|
||||||
if isV4 {
|
if isV4 {
|
||||||
for _, existing := range rs.A {
|
for _, existing := range rs.A {
|
||||||
if existing.Equal(ip) {
|
if existing.Equal(ip) {
|
||||||
@@ -97,7 +106,6 @@ func (s *DNSRecordStore) AddRecord(domain string, ip net.IP, siteId int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// AddPTRRecord adds a PTR record mapping an IP address to a domain name
|
// AddPTRRecord adds a PTR record mapping an IP address to a domain name
|
||||||
// ip should be a valid IPv4 or IPv6 address
|
// ip should be a valid IPv4 or IPv6 address
|
||||||
// domain should be in FQDN format (e.g., "example.com.")
|
// domain should be in FQDN format (e.g., "example.com.")
|
||||||
@@ -123,6 +131,16 @@ func (s *DNSRecordStore) AddPTRRecord(ip net.IP, domain string) error {
|
|||||||
// If ip is nil, removes all records for the domain (including wildcards)
|
// If ip is nil, removes all records for the domain (including wildcards)
|
||||||
// Automatically removes corresponding PTR records for non-wildcard domains
|
// Automatically removes corresponding PTR records for non-wildcard domains
|
||||||
func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
||||||
|
s.removeRecord(domain, ip, 0, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRecordForSite removes DNS records owned by a specific site.
|
||||||
|
// If ip is nil, it removes all records for the domain owned by that site.
|
||||||
|
func (s *DNSRecordStore) RemoveRecordForSite(domain string, ip net.IP, siteId int) {
|
||||||
|
s.removeRecord(domain, ip, siteId, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DNSRecordStore) removeRecord(domain string, ip net.IP, siteId int, bySite bool) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
@@ -142,8 +160,20 @@ func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
|||||||
if rs == nil {
|
if rs == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if rs.owners == nil {
|
||||||
|
rs.owners = make(map[string]map[int]bool)
|
||||||
|
}
|
||||||
|
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
|
if bySite {
|
||||||
|
rs.A = s.removeOwnedIPs(rs, rs.A, siteId, !isWildcard, domain)
|
||||||
|
rs.AAAA = s.removeOwnedIPs(rs, rs.AAAA, siteId, !isWildcard, domain)
|
||||||
|
if len(rs.A) == 0 && len(rs.AAAA) == 0 {
|
||||||
|
delete(m, domain)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all records for this domain
|
// Remove all records for this domain
|
||||||
if !isWildcard {
|
if !isWildcard {
|
||||||
for _, ipAddr := range rs.A {
|
for _, ipAddr := range rs.A {
|
||||||
@@ -162,6 +192,19 @@ func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove specific IP
|
// Remove specific IP
|
||||||
|
ipKey := ip.String()
|
||||||
|
if bySite {
|
||||||
|
owners := rs.owners[ipKey]
|
||||||
|
if len(owners) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
delete(owners, siteId)
|
||||||
|
if len(owners) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
delete(rs.owners, ipKey)
|
||||||
|
}
|
||||||
|
|
||||||
if ip.To4() != nil {
|
if ip.To4() != nil {
|
||||||
rs.A = removeIP(rs.A, ip)
|
rs.A = removeIP(rs.A, ip)
|
||||||
if !isWildcard {
|
if !isWildcard {
|
||||||
@@ -177,6 +220,7 @@ func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete(rs.owners, ipKey)
|
||||||
|
|
||||||
// Clean up empty record sets
|
// Clean up empty record sets
|
||||||
if len(rs.A) == 0 && len(rs.AAAA) == 0 {
|
if len(rs.A) == 0 && len(rs.AAAA) == 0 {
|
||||||
@@ -184,6 +228,33 @@ func (s *DNSRecordStore) RemoveRecord(domain string, ip net.IP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DNSRecordStore) removeOwnedIPs(rs *recordSet, ips []net.IP, siteId int, removePTR bool, domain string) []net.IP {
|
||||||
|
kept := make([]net.IP, 0, len(ips))
|
||||||
|
for _, ipAddr := range ips {
|
||||||
|
ipKey := ipAddr.String()
|
||||||
|
owners := rs.owners[ipKey]
|
||||||
|
if len(owners) == 0 {
|
||||||
|
kept = append(kept, ipAddr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(owners, siteId)
|
||||||
|
if len(owners) > 0 {
|
||||||
|
kept = append(kept, ipAddr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(rs.owners, ipKey)
|
||||||
|
if removePTR {
|
||||||
|
if ptrDomain, exists := s.ptrRecords[ipKey]; exists && ptrDomain == domain {
|
||||||
|
delete(s.ptrRecords, ipKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kept
|
||||||
|
}
|
||||||
|
|
||||||
// RemovePTRRecord removes a PTR record for an IP address
|
// RemovePTRRecord removes a PTR record for an IP address
|
||||||
func (s *DNSRecordStore) RemovePTRRecord(ip net.IP) {
|
func (s *DNSRecordStore) RemovePTRRecord(ip net.IP) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
|||||||
@@ -782,6 +782,37 @@ func TestAutomaticPTRRecordOnRemove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRemoveRecordForSiteKeepsSharedAliasIP(t *testing.T) {
|
||||||
|
store := NewDNSRecordStore()
|
||||||
|
|
||||||
|
domain := "shared.example.com."
|
||||||
|
ip := net.ParseIP("192.168.1.100")
|
||||||
|
|
||||||
|
if err := store.AddRecord(domain, ip, 10); err != nil {
|
||||||
|
t.Fatalf("Failed to add record for site 10: %v", err)
|
||||||
|
}
|
||||||
|
if err := store.AddRecord(domain, ip, 20); err != nil {
|
||||||
|
t.Fatalf("Failed to add record for site 20: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
store.RemoveRecordForSite(domain, ip, 10)
|
||||||
|
|
||||||
|
ips, exists := store.GetRecords(domain, RecordTypeA)
|
||||||
|
if !exists {
|
||||||
|
t.Fatal("Expected shared record to still exist after removing one site owner")
|
||||||
|
}
|
||||||
|
if len(ips) != 1 || !ips[0].Equal(ip) {
|
||||||
|
t.Fatalf("Expected shared IP to remain after first owner removal, got %v", ips)
|
||||||
|
}
|
||||||
|
|
||||||
|
store.RemoveRecordForSite(domain, ip, 20)
|
||||||
|
|
||||||
|
ips, exists = store.GetRecords(domain, RecordTypeA)
|
||||||
|
if exists {
|
||||||
|
t.Fatalf("Expected domain to be removed after last owner removal, got %v", ips)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAutomaticPTRRecordOnRemoveAll(t *testing.T) {
|
func TestAutomaticPTRRecordOnRemoveAll(t *testing.T) {
|
||||||
store := NewDNSRecordStore()
|
store := NewDNSRecordStore()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -768,7 +768,7 @@ func (pm *PeerManager) RemoveAlias(siteId int, aliasName string) error {
|
|||||||
if aliasToRemove != nil {
|
if aliasToRemove != nil {
|
||||||
address := net.ParseIP(aliasToRemove.AliasAddress)
|
address := net.ParseIP(aliasToRemove.AliasAddress)
|
||||||
if address != nil {
|
if address != nil {
|
||||||
pm.dnsProxy.RemoveDNSRecord(aliasName, address)
|
pm.dnsProxy.RemoveDNSRecordForSite(aliasName, address, siteId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user