mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-14 10:49:07 +02:00
[management] Canonicalize the proxy cluster address where it is stored
The proxy-connect path already computes the canonical form of the address a proxy declares — ValidateDomains returns lowercase punycode — and then throws it away, storing the string as declared. cluster_address is the key every capability, ownership and routing lookup matches on, so one host could sit in that column under two spellings, and the previous commit compensated with LOWER() in the ownership query, which gives up the cluster_address index on a query that runs for every account-scoped proxy connect. Keep the canonical form instead. Connect is the only writer of the column (heartbeats touch last_seen and status), and proxy rows are session state rebuilt on every connect rather than durable config, so the column converges without a migration and the lookups can stay exact and indexed. Folding happens before punycode conversion, not after: idna lowercases the ASCII it produces but does not case-fold the unicode it consumes, so PRÖXY.example.com and pröxy.example.com would otherwise encode to two different labels for one host. The agent network check keeps comparing normalised forms in memory, which costs nothing there — it is a pass over the account's cluster list, not a query — and covers rows written before this landed.
This commit is contained in:
@@ -6394,14 +6394,14 @@ func (s *SqlStore) HasActiveProxyAtClusterAddress(ctx context.Context, clusterAd
|
||||
|
||||
// IsClusterAddressConflicting reports whether the address is already declared
|
||||
// by a proxy outside the account — a shared proxy or another account's. The
|
||||
// comparison is case-insensitive: cluster addresses are hostnames, stored as
|
||||
// the proxy declared them, so two spellings of one host are one cluster and
|
||||
// must conflict rather than being claimable side by side.
|
||||
// match is exact, and stays exact so it uses the cluster_address index:
|
||||
// addresses are canonicalised where they are written (canonicalProxyAddress on
|
||||
// the proxy-connect path), so one host has one spelling in this column.
|
||||
func (s *SqlStore) IsClusterAddressConflicting(ctx context.Context, clusterAddress, accountID string) (bool, error) {
|
||||
var count int64
|
||||
result := s.db.
|
||||
Model(&proxy.Proxy{}).
|
||||
Where("LOWER(cluster_address) = LOWER(?) AND (account_id IS NULL OR account_id != ?)", clusterAddress, accountID).
|
||||
Where("cluster_address = ? AND (account_id IS NULL OR account_id != ?)", clusterAddress, accountID).
|
||||
Count(&count)
|
||||
if result.Error != nil {
|
||||
return false, status.Errorf(status.Internal, "check cluster address conflict: %v", result.Error)
|
||||
|
||||
Reference in New Issue
Block a user