@ -94,18 +94,24 @@ func main() {
}
}
ignoreDstTable . Insert ( pfx , true )
ignoreDstTable . Insert ( pfx , true )
}
}
var v4Prefixes [ ] netip . Prefix
var (
v4Prefixes [ ] netip . Prefix
numV4DNSAddrs int
)
for _ , s := range strings . Split ( * v4PfxStr , "," ) {
for _ , s := range strings . Split ( * v4PfxStr , "," ) {
p := netip . MustParsePrefix ( strings . TrimSpace ( s ) )
p := netip . MustParsePrefix ( strings . TrimSpace ( s ) )
if p . Masked ( ) != p {
if p . Masked ( ) != p {
log . Fatalf ( "v4 prefix %v is not a masked prefix" , p )
log . Fatalf ( "v4 prefix %v is not a masked prefix" , p )
}
}
v4Prefixes = append ( v4Prefixes , p )
v4Prefixes = append ( v4Prefixes , p )
numIPs := 1 << ( 32 - p . Bits ( ) )
numV4DNSAddrs += numIPs
}
}
if len ( v4Prefixes ) == 0 {
if len ( v4Prefixes ) == 0 {
log . Fatalf ( "no v4 prefixes specified" )
log . Fatalf ( "no v4 prefixes specified" )
}
}
dnsAddr := v4Prefixes [ 0 ] . Addr ( )
dnsAddr := v4Prefixes [ 0 ] . Addr ( )
numV4DNSAddrs -= 1 // Subtract the dnsAddr allocated above.
ts := & tsnet . Server {
ts := & tsnet . Server {
Hostname : * hostname ,
Hostname : * hostname ,
}
}
@ -157,6 +163,7 @@ func main() {
lc : lc ,
lc : lc ,
dnsAddr : dnsAddr ,
dnsAddr : dnsAddr ,
v4Ranges : v4Prefixes ,
v4Ranges : v4Prefixes ,
numV4DNSAddrs : numV4DNSAddrs ,
v6ULA : ula ( uint16 ( * siteID ) ) ,
v6ULA : ula ( uint16 ( * siteID ) ) ,
ignoreDsts : ignoreDstTable ,
ignoreDsts : ignoreDstTable ,
}
}
@ -177,6 +184,11 @@ type connector struct {
// v4Ranges is the list of IPv4 ranges to advertise and assign addresses from.
// v4Ranges is the list of IPv4 ranges to advertise and assign addresses from.
// These are masked prefixes.
// These are masked prefixes.
v4Ranges [ ] netip . Prefix
v4Ranges [ ] netip . Prefix
// numV4DNSAddrs is the total size of the IPv4 ranges in addresses, minus the
// dnsAddr allocation.
numV4DNSAddrs int
// v6ULA is the ULA prefix used by the app connector to assign IPv6 addresses.
// v6ULA is the ULA prefix used by the app connector to assign IPv6 addresses.
v6ULA netip . Prefix
v6ULA netip . Prefix
@ -502,6 +514,7 @@ type perPeerState struct {
mu sync . Mutex
mu sync . Mutex
domainToAddr map [ string ] [ ] netip . Addr
domainToAddr map [ string ] [ ] netip . Addr
addrToDomain * bart . Table [ string ]
addrToDomain * bart . Table [ string ]
numV4Allocs int
}
}
// domainForIP returns the domain name assigned to the given IP address and
// domainForIP returns the domain name assigned to the given IP address and
@ -547,17 +560,25 @@ func (ps *perPeerState) isIPUsedLocked(ip netip.Addr) bool {
// unusedIPv4Locked returns an unused IPv4 address from the available ranges.
// unusedIPv4Locked returns an unused IPv4 address from the available ranges.
func ( ps * perPeerState ) unusedIPv4Locked ( ) netip . Addr {
func ( ps * perPeerState ) unusedIPv4Locked ( ) netip . Addr {
// All addresses have been allocated.
if ps . numV4Allocs >= ps . c . numV4DNSAddrs {
return netip . Addr { }
}
// TODO: skip ranges that have been exhausted
// TODO: skip ranges that have been exhausted
// TODO: implement a much more efficient algorithm for finding unused IPs,
// this is fairly crazy.
for {
for _ , r := range ps . c . v4Ranges {
for _ , r := range ps . c . v4Ranges {
ip := randV4 ( r )
ip := randV4 ( r )
for r . Contains ( ip ) {
if ! r . Contains ( ip ) {
panic ( "error: randV4 returned invalid address" )
}
if ! ps . isIPUsedLocked ( ip ) && ip != ps . c . dnsAddr {
if ! ps . isIPUsedLocked ( ip ) && ip != ps . c . dnsAddr {
return ip
return ip
}
}
ip = ip . Next ( )
}
}
}
}
return netip . Addr { }
}
}
// randV4 returns a random IPv4 address within the given prefix.
// randV4 returns a random IPv4 address within the given prefix.
@ -583,6 +604,7 @@ func (ps *perPeerState) assignAddrsLocked(domain string) []netip.Addr {
if ! v4 . IsValid ( ) {
if ! v4 . IsValid ( ) {
return nil
return nil
}
}
ps . numV4Allocs ++
as16 := ps . c . v6ULA . Addr ( ) . As16 ( )
as16 := ps . c . v6ULA . Addr ( ) . As16 ( )
as4 := v4 . As4 ( )
as4 := v4 . As4 ( )
copy ( as16 [ 12 : ] , as4 [ : ] )
copy ( as16 [ 12 : ] , as4 [ : ] )