Some checks failed
Bearer / scan (push) Successful in 9s
Go Build Multi-Platform / build (amd64, linux) (push) Successful in 42s
Go Build Multi-Platform / build (amd64, darwin) (push) Successful in 44s
Go Build Multi-Platform / build (arm, freebsd) (push) Successful in 41s
Go Build Multi-Platform / build (arm, windows) (push) Successful in 39s
Go Build Multi-Platform / build (arm64, windows) (push) Successful in 1m8s
Go Build Multi-Platform / build (wasm, js) (push) Successful in 1m6s
TinyGo Build / tinygo-build (tinygo-wasm, tinygo-wasm, reticulum-go.wasm, wasm) (pull_request) Failing after 1m2s
TinyGo Build / tinygo-build (tinygo-build, tinygo-default, reticulum-go-tinygo, ) (pull_request) Failing after 1m4s
Go Revive Lint / lint (push) Successful in 1m4s
Go Test Multi-Platform / Test (ubuntu-latest, arm64) (push) Successful in 1m24s
Run Gosec / tests (push) Successful in 1m29s
Go Test Multi-Platform / Test (ubuntu-latest, amd64) (push) Successful in 2m31s
Go Build Multi-Platform / build (amd64, freebsd) (push) Successful in 9m28s
Go Build Multi-Platform / build (arm, linux) (push) Successful in 9m28s
Go Build Multi-Platform / build (amd64, windows) (push) Successful in 9m30s
Go Build Multi-Platform / build (arm64, darwin) (push) Successful in 9m27s
Go Build Multi-Platform / build (arm64, linux) (push) Successful in 9m26s
Go Build Multi-Platform / build (arm64, freebsd) (push) Successful in 9m29s
Go Build Multi-Platform / Create Release (push) Has been skipped
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
// SPDX-License-Identifier: 0BSD
|
|
// Copyright (c) 2024-2026 Sudo-Ivan / Quad4.io
|
|
package resolver
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"strings"
|
|
"sync"
|
|
|
|
"git.quad4.io/Networks/Reticulum-Go/pkg/identity"
|
|
)
|
|
|
|
const (
|
|
// Hash length conversion (bits to bytes)
|
|
BitsPerByte = 8
|
|
|
|
// Known destination data index
|
|
KnownDestIdentityIndex = 2
|
|
|
|
// Minimum name parts for hierarchical resolution
|
|
MinNameParts = 2
|
|
)
|
|
|
|
type Resolver struct {
|
|
cache map[string]*identity.Identity
|
|
cacheLock sync.RWMutex
|
|
}
|
|
|
|
func New() *Resolver {
|
|
return &Resolver{
|
|
cache: make(map[string]*identity.Identity),
|
|
}
|
|
}
|
|
|
|
func (r *Resolver) ResolveIdentity(fullName string) (*identity.Identity, error) {
|
|
if fullName == "" {
|
|
return nil, errors.New("empty identity name")
|
|
}
|
|
|
|
r.cacheLock.RLock()
|
|
if cachedIdentity, exists := r.cache[fullName]; exists {
|
|
r.cacheLock.RUnlock()
|
|
return cachedIdentity, nil
|
|
}
|
|
r.cacheLock.RUnlock()
|
|
|
|
// Hash the full name to create a deterministic identity
|
|
h := sha256.New()
|
|
h.Write([]byte(fullName))
|
|
nameHash := h.Sum(nil)[:identity.NAME_HASH_LENGTH/BitsPerByte]
|
|
hashStr := hex.EncodeToString(nameHash)
|
|
|
|
// Check if this identity is known
|
|
if knownData, exists := identity.GetKnownDestination(hashStr); exists {
|
|
if id, ok := knownData[KnownDestIdentityIndex].(*identity.Identity); ok {
|
|
r.cacheLock.Lock()
|
|
r.cache[fullName] = id
|
|
r.cacheLock.Unlock()
|
|
return id, nil
|
|
}
|
|
}
|
|
|
|
// Split name into parts for hierarchical resolution
|
|
parts := strings.Split(fullName, ".")
|
|
if len(parts) < MinNameParts {
|
|
return nil, errors.New("invalid identity name format")
|
|
}
|
|
|
|
// Create new identity if not found
|
|
id, err := identity.New()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
r.cacheLock.Lock()
|
|
r.cache[fullName] = id
|
|
r.cacheLock.Unlock()
|
|
|
|
return id, nil
|
|
}
|
|
|
|
func ResolveIdentity(fullName string) (*identity.Identity, error) {
|
|
r := New()
|
|
return r.ResolveIdentity(fullName)
|
|
}
|