118 lines
3.0 KiB
Go
118 lines
3.0 KiB
Go
package app
|
|
|
|
import (
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
egressutilpkg "selective-vpn-api/app/egressutil"
|
|
)
|
|
|
|
func (s *egressIdentityService) refreshScope(target egressScopeTarget, force bool) {
|
|
s.acquire()
|
|
defer s.release()
|
|
|
|
now := time.Now().UTC()
|
|
provider := s.providerFor(target.Source)
|
|
if provider == nil {
|
|
s.finishError(target, "provider is not configured for scope source", now)
|
|
return
|
|
}
|
|
|
|
ip, err := provider.Probe(target)
|
|
if err != nil {
|
|
s.finishError(target, err.Error(), now)
|
|
return
|
|
}
|
|
|
|
code, name, geoErr := s.lookupGeo(ip, force)
|
|
s.finishSuccess(target, ip, code, name, geoErr, now)
|
|
}
|
|
|
|
func (s *egressIdentityService) providerFor(source string) egressSourceProvider {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
return s.providers[strings.ToLower(strings.TrimSpace(source))]
|
|
}
|
|
|
|
func (s *egressIdentityService) finishError(target egressScopeTarget, msg string, at time.Time) {
|
|
s.mu.Lock()
|
|
entry := s.ensureEntryLocked(target)
|
|
prev := s.entrySnapshotLocked(entry, target, at)
|
|
entry.swr.finishError(msg, at)
|
|
next := s.entrySnapshotLocked(entry, target, at)
|
|
changed := egressIdentityChanged(prev, next)
|
|
s.mu.Unlock()
|
|
|
|
if changed {
|
|
events.push("egress_identity_changed", map[string]any{
|
|
"scope": next.Scope,
|
|
"ip": next.IP,
|
|
"country_code": next.CountryCode,
|
|
"country_name": next.CountryName,
|
|
"updated_at": next.UpdatedAt,
|
|
"stale": next.Stale,
|
|
"last_error": next.LastError,
|
|
})
|
|
if target.Source == "transport" {
|
|
publishTransportRuntimeObservabilitySnapshotChanged(
|
|
"egress_identity_changed",
|
|
[]string{target.SourceID},
|
|
nil,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *egressIdentityService) finishSuccess(
|
|
target egressScopeTarget,
|
|
ip string,
|
|
code string,
|
|
name string,
|
|
geoErr error,
|
|
at time.Time,
|
|
) {
|
|
s.mu.Lock()
|
|
entry := s.ensureEntryLocked(target)
|
|
prev := s.entrySnapshotLocked(entry, target, at)
|
|
|
|
previousIP := strings.TrimSpace(entry.item.IP)
|
|
entry.item.Scope = target.Scope
|
|
entry.item.Source = target.Source
|
|
entry.item.SourceID = target.SourceID
|
|
entry.item.IP = strings.TrimSpace(ip)
|
|
if geoErr == nil {
|
|
entry.item.CountryCode = egressutilpkg.NormalizeCountryCode(code)
|
|
entry.item.CountryName = strings.TrimSpace(name)
|
|
} else if previousIP != strings.TrimSpace(ip) {
|
|
entry.item.CountryCode = ""
|
|
entry.item.CountryName = ""
|
|
}
|
|
entry.swr.finishSuccess(at)
|
|
next := s.entrySnapshotLocked(entry, target, at)
|
|
changed := egressIdentityChanged(prev, next)
|
|
s.mu.Unlock()
|
|
|
|
if geoErr != nil {
|
|
log.Printf("egress geo lookup warning: scope=%s ip=%s err=%v", target.Scope, ip, geoErr)
|
|
}
|
|
if changed {
|
|
events.push("egress_identity_changed", map[string]any{
|
|
"scope": next.Scope,
|
|
"ip": next.IP,
|
|
"country_code": next.CountryCode,
|
|
"country_name": next.CountryName,
|
|
"updated_at": next.UpdatedAt,
|
|
"stale": next.Stale,
|
|
"last_error": next.LastError,
|
|
})
|
|
if target.Source == "transport" {
|
|
publishTransportRuntimeObservabilitySnapshotChanged(
|
|
"egress_identity_changed",
|
|
[]string{target.SourceID},
|
|
nil,
|
|
)
|
|
}
|
|
}
|
|
}
|