mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-16 18:11:58 +02:00
94 lines
2.4 KiB
Go
94 lines
2.4 KiB
Go
package fakeip
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"sync"
|
|
)
|
|
|
|
// Manager manages allocation of fake IPs from the 240.0.0.0/8 block
|
|
type Manager struct {
|
|
mu sync.Mutex
|
|
nextIP netip.Addr // Next IP to allocate
|
|
allocated map[netip.Addr]netip.Addr // real IP -> fake IP
|
|
fakeToReal map[netip.Addr]netip.Addr // fake IP -> real IP
|
|
baseIP netip.Addr // First usable IP: 240.0.0.1
|
|
maxIP netip.Addr // Last usable IP: 240.255.255.254
|
|
}
|
|
|
|
// NewManager creates a new fake IP manager using 240.0.0.0/8 block
|
|
func NewManager() *Manager {
|
|
baseIP := netip.AddrFrom4([4]byte{240, 0, 0, 1})
|
|
maxIP := netip.AddrFrom4([4]byte{240, 255, 255, 254})
|
|
|
|
return &Manager{
|
|
nextIP: baseIP,
|
|
allocated: make(map[netip.Addr]netip.Addr),
|
|
fakeToReal: make(map[netip.Addr]netip.Addr),
|
|
baseIP: baseIP,
|
|
maxIP: maxIP,
|
|
}
|
|
}
|
|
|
|
// AllocateFakeIP allocates a fake IP for the given real IP
|
|
// Returns the fake IP, or existing fake IP if already allocated
|
|
func (m *Manager) AllocateFakeIP(realIP netip.Addr) (netip.Addr, error) {
|
|
if !realIP.Is4() {
|
|
return netip.Addr{}, fmt.Errorf("only IPv4 addresses supported")
|
|
}
|
|
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
if fakeIP, exists := m.allocated[realIP]; exists {
|
|
return fakeIP, nil
|
|
}
|
|
|
|
startIP := m.nextIP
|
|
for {
|
|
currentIP := m.nextIP
|
|
|
|
// Advance to next IP, wrapping at boundary
|
|
if m.nextIP.Compare(m.maxIP) >= 0 {
|
|
m.nextIP = m.baseIP
|
|
} else {
|
|
m.nextIP = m.nextIP.Next()
|
|
}
|
|
|
|
// Check if current IP is available
|
|
if _, inUse := m.fakeToReal[currentIP]; !inUse {
|
|
m.allocated[realIP] = currentIP
|
|
m.fakeToReal[currentIP] = realIP
|
|
return currentIP, nil
|
|
}
|
|
|
|
// Prevent infinite loop if all IPs exhausted
|
|
if m.nextIP.Compare(startIP) == 0 {
|
|
return netip.Addr{}, fmt.Errorf("no more fake IPs available in 240.0.0.0/8 block")
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetFakeIP returns the fake IP for a real IP if it exists
|
|
func (m *Manager) GetFakeIP(realIP netip.Addr) (netip.Addr, bool) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
fakeIP, exists := m.allocated[realIP]
|
|
return fakeIP, exists
|
|
}
|
|
|
|
// GetRealIP returns the real IP for a fake IP if it exists, otherwise false
|
|
func (m *Manager) GetRealIP(fakeIP netip.Addr) (netip.Addr, bool) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
realIP, exists := m.fakeToReal[fakeIP]
|
|
return realIP, exists
|
|
}
|
|
|
|
// GetFakeIPBlock returns the fake IP block used by this manager
|
|
func (m *Manager) GetFakeIPBlock() netip.Prefix {
|
|
return netip.MustParsePrefix("240.0.0.0/8")
|
|
}
|