96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func (egressSystemProvider) Probe(_ egressScopeTarget) (string, error) {
|
|
return egressProbeExternalIP()
|
|
}
|
|
|
|
func (egressAdGuardProvider) Probe(_ egressScopeTarget) (string, error) {
|
|
stdout, stderr, code, err := runCommandTimeout(2*time.Second, "systemctl", "is-active", adgvpnUnit)
|
|
state := strings.ToLower(strings.TrimSpace(stdout))
|
|
if state != "active" || err != nil || code != 0 {
|
|
return "", transportCommandError("systemctl is-active "+adgvpnUnit, stdout, stderr, code, err)
|
|
}
|
|
|
|
iface, _ := resolveTrafficIface(loadTrafficModeState().PreferredIface)
|
|
if iface = strings.TrimSpace(iface); iface == "" {
|
|
return "", fmt.Errorf("adguardvpn interface is not resolved")
|
|
}
|
|
if !ifaceExists(iface) {
|
|
return "", fmt.Errorf("adguardvpn interface %q is not available", iface)
|
|
}
|
|
return egressProbeExternalIPViaInterface(iface)
|
|
}
|
|
|
|
func (egressTransportProvider) Probe(target egressScopeTarget) (string, error) {
|
|
id := sanitizeID(target.SourceID)
|
|
if id == "" {
|
|
return "", fmt.Errorf("invalid transport source id")
|
|
}
|
|
|
|
transportMu.Lock()
|
|
st := loadTransportClientsState()
|
|
idx := findTransportClientIndex(st.Items, id)
|
|
var client TransportClient
|
|
if idx >= 0 {
|
|
client = st.Items[idx]
|
|
}
|
|
transportMu.Unlock()
|
|
|
|
if idx < 0 {
|
|
return "", fmt.Errorf("transport client %q not found", id)
|
|
}
|
|
if !client.Enabled {
|
|
return "", fmt.Errorf("transport client %q is disabled", id)
|
|
}
|
|
if normalizeTransportStatus(client.Status) == TransportClientDown {
|
|
backend := selectTransportBackend(client)
|
|
live := backend.Health(client)
|
|
if normalizeTransportStatus(live.Status) != TransportClientUp {
|
|
msg := strings.TrimSpace(live.Message)
|
|
if msg == "" {
|
|
msg = fmt.Sprintf("transport client %q is down", id)
|
|
}
|
|
return "", fmt.Errorf("%s", msg)
|
|
}
|
|
client.Status = TransportClientUp
|
|
}
|
|
|
|
if transportNetnsEnabled(client) {
|
|
ns := transportNetnsName(client)
|
|
if strings.TrimSpace(ns) == "" {
|
|
return "", fmt.Errorf("transport client %q netns is enabled but netns_name is empty", id)
|
|
}
|
|
if client.Kind == TransportClientSingBox {
|
|
proxyURL := egressSingBoxSOCKSProxyURL(client)
|
|
if proxyURL == "" {
|
|
return "", fmt.Errorf("proxy probe failed: singbox socks inbound not found")
|
|
}
|
|
// For SingBox in netns we must use tunnel egress probe (SOCKS inbound -> outbound proxy).
|
|
// Direct netns probe is intentionally not used: in selective mode it may return AdGuard/system IP.
|
|
ip, err := egressProbeExternalIPInNetnsViaProxy(client, ns, proxyURL)
|
|
if err == nil {
|
|
return ip, nil
|
|
}
|
|
return "", fmt.Errorf("proxy probe failed: %v", err)
|
|
}
|
|
|
|
ip, err := egressProbeExternalIPInNetns(client, ns)
|
|
if err == nil {
|
|
return ip, nil
|
|
}
|
|
return "", err
|
|
}
|
|
|
|
iface := strings.TrimSpace(client.Iface)
|
|
if iface != "" && ifaceExists(iface) {
|
|
return egressProbeExternalIPViaInterface(iface)
|
|
}
|
|
return egressProbeExternalIP()
|
|
}
|