package children import ( "fmt" "net/netip" "sync" ) type nebulaDeviceNamerKey struct { networkID string deviceIP netip.Addr } // NebulaDeviceNamer is used to assign unique TUN device names to different // nebula networks running on the same host. It is intended to be shared amongst // all running Children instances so that they do not accidentally conflict in // TUN device names. // // NebulaDeviceNamer is thread-safe. type NebulaDeviceNamer struct { l sync.Mutex counter uint64 assigned map[nebulaDeviceNamerKey]string } // NewNebulaDeviceNamer initializes and returns a new instance. func NewNebulaDeviceNamer() *NebulaDeviceNamer { return &NebulaDeviceNamer{ assigned: map[nebulaDeviceNamerKey]string{}, } } // getName returns a unique TUN device name for the given network and IP, // generating a new one if the ID has never been given before. func (n *NebulaDeviceNamer) getName(networkID string, ip netip.Addr) string { key := nebulaDeviceNamerKey{networkID, ip} n.l.Lock() defer n.l.Unlock() if name, ok := n.assigned[key]; ok { return name } i := n.counter n.counter++ name := fmt.Sprintf("isle%d-%s", i, networkID) n.assigned[key] = name return name }