326 lines
12 KiB
Go
326 lines
12 KiB
Go
package app
|
|
|
|
// ---------------------------------------------------------------------
|
|
// структуры
|
|
// ---------------------------------------------------------------------
|
|
|
|
// EN: Shared DTO/model definitions exchanged between HTTP handlers, workers,
|
|
// EN: SSE stream, and internal orchestration logic.
|
|
// RU: Общие DTO/модели, которыми обмениваются HTTP-обработчики, воркеры,
|
|
// RU: SSE-поток и внутренняя оркестрация.
|
|
|
|
type Status struct {
|
|
Timestamp string `json:"timestamp"`
|
|
IPCount int `json:"ip_count"`
|
|
DomainCount int `json:"domain_count"`
|
|
Iface string `json:"iface"`
|
|
Table string `json:"table"`
|
|
Mark string `json:"mark"`
|
|
|
|
PolicyRouteOK *bool `json:"policy_route_ok,omitempty"`
|
|
RouteOK *bool `json:"route_ok,omitempty"`
|
|
}
|
|
|
|
type cmdResult struct {
|
|
OK bool `json:"ok"`
|
|
Message string `json:"message,omitempty"`
|
|
ExitCode int `json:"exitCode,omitempty"`
|
|
Stdout string `json:"stdout,omitempty"`
|
|
Stderr string `json:"stderr,omitempty"`
|
|
}
|
|
|
|
type VPNLoginState struct {
|
|
State string `json:"state"`
|
|
Email string `json:"email,omitempty"`
|
|
Msg string `json:"msg,omitempty"`
|
|
|
|
// для GUI
|
|
Text string `json:"text,omitempty"`
|
|
Color string `json:"color,omitempty"`
|
|
}
|
|
|
|
type DNSUpstreams struct {
|
|
Default1 string `json:"default1"`
|
|
Default2 string `json:"default2"`
|
|
Meta1 string `json:"meta1"`
|
|
Meta2 string `json:"meta2"`
|
|
}
|
|
|
|
type DNSResolverMode string
|
|
|
|
const (
|
|
DNSModeDirect DNSResolverMode = "direct"
|
|
DNSModeSmartDNS DNSResolverMode = "smartdns"
|
|
DNSModeHybridWildcard DNSResolverMode = "hybrid_wildcard"
|
|
)
|
|
|
|
type DNSMode struct {
|
|
ViaSmartDNS bool `json:"via_smartdns"`
|
|
SmartDNSAddr string `json:"smartdns_addr"`
|
|
Mode DNSResolverMode `json:"mode"`
|
|
}
|
|
|
|
type DNSStatusResponse struct {
|
|
ViaSmartDNS bool `json:"via_smartdns"`
|
|
SmartDNSAddr string `json:"smartdns_addr"`
|
|
Mode DNSResolverMode `json:"mode"`
|
|
UnitState string `json:"unit_state"`
|
|
RuntimeNftset bool `json:"runtime_nftset"`
|
|
WildcardSource string `json:"wildcard_source"`
|
|
RuntimeCfgPath string `json:"runtime_config_path,omitempty"`
|
|
RuntimeCfgError string `json:"runtime_config_error,omitempty"`
|
|
}
|
|
|
|
type DNSModeRequest struct {
|
|
ViaSmartDNS bool `json:"via_smartdns"`
|
|
SmartDNSAddr string `json:"smartdns_addr"`
|
|
Mode DNSResolverMode `json:"mode"`
|
|
}
|
|
|
|
type SmartDNSRuntimeStatusResponse struct {
|
|
Enabled bool `json:"enabled"`
|
|
AppliedEnable bool `json:"applied_enabled"`
|
|
WildcardSource string `json:"wildcard_source"`
|
|
UnitState string `json:"unit_state"`
|
|
ConfigPath string `json:"config_path"`
|
|
Changed bool `json:"changed,omitempty"`
|
|
Restarted bool `json:"restarted,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
}
|
|
|
|
type SmartDNSRuntimeRequest struct {
|
|
Enabled *bool `json:"enabled"`
|
|
Restart *bool `json:"restart,omitempty"`
|
|
}
|
|
|
|
type TrafficMode string
|
|
|
|
const (
|
|
TrafficModeSelective TrafficMode = "selective"
|
|
TrafficModeFullTunnel TrafficMode = "full_tunnel"
|
|
TrafficModeDirect TrafficMode = "direct"
|
|
)
|
|
|
|
type TrafficModeState struct {
|
|
Mode TrafficMode `json:"mode"`
|
|
PreferredIface string `json:"preferred_iface,omitempty"`
|
|
AutoLocalBypass bool `json:"auto_local_bypass"`
|
|
ForceVPNSubnets []string `json:"force_vpn_subnets,omitempty"`
|
|
ForceVPNUIDs []string `json:"force_vpn_uids,omitempty"`
|
|
ForceVPNCGroups []string `json:"force_vpn_cgroups,omitempty"`
|
|
ForceDirectSubnets []string `json:"force_direct_subnets,omitempty"`
|
|
ForceDirectUIDs []string `json:"force_direct_uids,omitempty"`
|
|
ForceDirectCGroups []string `json:"force_direct_cgroups,omitempty"`
|
|
UpdatedAt string `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
type TrafficModeRequest struct {
|
|
Mode TrafficMode `json:"mode"`
|
|
PreferredIface *string `json:"preferred_iface,omitempty"`
|
|
AutoLocalBypass *bool `json:"auto_local_bypass,omitempty"`
|
|
ForceVPNSubnets *[]string `json:"force_vpn_subnets,omitempty"`
|
|
ForceVPNUIDs *[]string `json:"force_vpn_uids,omitempty"`
|
|
ForceVPNCGroups *[]string `json:"force_vpn_cgroups,omitempty"`
|
|
ForceDirectSubnets *[]string `json:"force_direct_subnets,omitempty"`
|
|
ForceDirectUIDs *[]string `json:"force_direct_uids,omitempty"`
|
|
ForceDirectCGroups *[]string `json:"force_direct_cgroups,omitempty"`
|
|
}
|
|
|
|
type TrafficModeStatusResponse struct {
|
|
Mode TrafficMode `json:"mode"`
|
|
DesiredMode TrafficMode `json:"desired_mode"`
|
|
AppliedMode TrafficMode `json:"applied_mode"`
|
|
PreferredIface string `json:"preferred_iface,omitempty"`
|
|
AutoLocalBypass bool `json:"auto_local_bypass"`
|
|
BypassCandidates int `json:"bypass_candidates"`
|
|
ForceVPNSubnets []string `json:"force_vpn_subnets,omitempty"`
|
|
ForceVPNUIDs []string `json:"force_vpn_uids,omitempty"`
|
|
ForceVPNCGroups []string `json:"force_vpn_cgroups,omitempty"`
|
|
ForceDirectSubnets []string `json:"force_direct_subnets,omitempty"`
|
|
ForceDirectUIDs []string `json:"force_direct_uids,omitempty"`
|
|
ForceDirectCGroups []string `json:"force_direct_cgroups,omitempty"`
|
|
OverridesApplied int `json:"overrides_applied"`
|
|
CgroupResolvedUIDs int `json:"cgroup_resolved_uids"`
|
|
CgroupWarning string `json:"cgroup_warning,omitempty"`
|
|
ActiveIface string `json:"active_iface,omitempty"`
|
|
IfaceReason string `json:"iface_reason,omitempty"`
|
|
RuleMark bool `json:"rule_mark"`
|
|
RuleFull bool `json:"rule_full"`
|
|
TableDefault bool `json:"table_default"`
|
|
ProbeOK bool `json:"probe_ok"`
|
|
ProbeMessage string `json:"probe_message,omitempty"`
|
|
Healthy bool `json:"healthy"`
|
|
Message string `json:"message,omitempty"`
|
|
}
|
|
|
|
type TrafficCandidateSubnet struct {
|
|
CIDR string `json:"cidr"`
|
|
Dev string `json:"dev,omitempty"`
|
|
Kind string `json:"kind,omitempty"` // lan|docker|link
|
|
LinkDown bool `json:"linkdown,omitempty"`
|
|
}
|
|
|
|
type TrafficCandidateUnit struct {
|
|
Unit string `json:"unit"`
|
|
Description string `json:"description,omitempty"`
|
|
Cgroup string `json:"cgroup,omitempty"`
|
|
}
|
|
|
|
type TrafficCandidateUID struct {
|
|
UID int `json:"uid"`
|
|
User string `json:"user,omitempty"`
|
|
Examples []string `json:"examples,omitempty"`
|
|
}
|
|
|
|
type TrafficCandidatesResponse struct {
|
|
GeneratedAt string `json:"generated_at"`
|
|
Subnets []TrafficCandidateSubnet `json:"subnets,omitempty"`
|
|
Units []TrafficCandidateUnit `json:"units,omitempty"`
|
|
UIDs []TrafficCandidateUID `json:"uids,omitempty"`
|
|
}
|
|
type TrafficInterfacesResponse struct {
|
|
Interfaces []string `json:"interfaces"`
|
|
PreferredIface string `json:"preferred_iface,omitempty"`
|
|
ActiveIface string `json:"active_iface,omitempty"`
|
|
IfaceReason string `json:"iface_reason,omitempty"`
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// traffic app marks (per-app routing via cgroup -> fwmark)
|
|
// ---------------------------------------------------------------------
|
|
|
|
type TrafficAppMarksOp string
|
|
|
|
const (
|
|
TrafficAppMarksAdd TrafficAppMarksOp = "add"
|
|
TrafficAppMarksDel TrafficAppMarksOp = "del"
|
|
TrafficAppMarksClear TrafficAppMarksOp = "clear"
|
|
)
|
|
|
|
// EN: Runtime app marking request. Used by per-app launcher wrappers.
|
|
// RU: Runtime app marking запрос. Используется wrapper-лаунчером per-app.
|
|
type TrafficAppMarksRequest struct {
|
|
Op TrafficAppMarksOp `json:"op"`
|
|
Target string `json:"target"` // vpn|direct
|
|
Cgroup string `json:"cgroup,omitempty"`
|
|
// EN: Optional metadata to deduplicate marks per-app across restarts / re-runs.
|
|
// RU: Опциональные метаданные, чтобы не плодить метки на одно и то же приложение.
|
|
Unit string `json:"unit,omitempty"`
|
|
Command string `json:"command,omitempty"`
|
|
AppKey string `json:"app_key,omitempty"`
|
|
TimeoutSec int `json:"timeout_sec,omitempty"` // only for add
|
|
}
|
|
|
|
type TrafficAppMarksResponse struct {
|
|
OK bool `json:"ok"`
|
|
Message string `json:"message,omitempty"`
|
|
Op string `json:"op,omitempty"`
|
|
Target string `json:"target,omitempty"`
|
|
Cgroup string `json:"cgroup,omitempty"`
|
|
CgroupID uint64 `json:"cgroup_id,omitempty"`
|
|
TimeoutSec int `json:"timeout_sec,omitempty"`
|
|
}
|
|
|
|
type TrafficAppMarksStatusResponse struct {
|
|
VPNCount int `json:"vpn_count"`
|
|
DirectCount int `json:"direct_count"`
|
|
Message string `json:"message,omitempty"`
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// traffic app profiles (persistent app launcher configs)
|
|
// ---------------------------------------------------------------------
|
|
|
|
// EN: Persistent per-app launcher profile (separate from runtime marks).
|
|
// RU: Постоянный профиль запуска приложения (отдельно от runtime marks).
|
|
type TrafficAppProfile struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name,omitempty"`
|
|
AppKey string `json:"app_key,omitempty"`
|
|
Command string `json:"command,omitempty"`
|
|
Target string `json:"target,omitempty"` // vpn|direct
|
|
TTLSec int `json:"ttl_sec,omitempty"`
|
|
VPNProfile string `json:"vpn_profile,omitempty"`
|
|
CreatedAt string `json:"created_at,omitempty"`
|
|
UpdatedAt string `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
type TrafficAppProfilesResponse struct {
|
|
Profiles []TrafficAppProfile `json:"profiles"`
|
|
Message string `json:"message,omitempty"`
|
|
}
|
|
|
|
type TrafficAppProfileUpsertRequest struct {
|
|
ID string `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
AppKey string `json:"app_key,omitempty"`
|
|
Command string `json:"command,omitempty"`
|
|
Target string `json:"target,omitempty"` // vpn|direct
|
|
TTLSec int `json:"ttl_sec,omitempty"`
|
|
VPNProfile string `json:"vpn_profile,omitempty"`
|
|
}
|
|
|
|
type SystemdState struct {
|
|
State string `json:"state"`
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// события / SSE
|
|
// ---------------------------------------------------------------------
|
|
|
|
type Event struct {
|
|
ID int64 `json:"id"`
|
|
Kind string `json:"kind"`
|
|
Ts string `json:"ts"`
|
|
Data interface{} `json:"data,omitempty"`
|
|
}
|
|
|
|
// EN: Callback for streaming user-visible progress from long-running nft updates.
|
|
// RU: Колбэк для отправки прогресса длительных nft-операций в пользовательский интерфейс.
|
|
type ProgressCallback func(percent int, message string)
|
|
|
|
// ---------------------------------------------------------------------
|
|
// resolver модели
|
|
// ---------------------------------------------------------------------
|
|
|
|
// EN: Input contract for the Go-based domain resolver job.
|
|
// RU: Контракт входных параметров для Go-резолвера доменов.
|
|
type ResolverOpts struct {
|
|
DomainsPath string
|
|
MetaPath string
|
|
StaticPath string
|
|
CachePath string
|
|
PtrCachePath string
|
|
TraceLog string
|
|
TTL int
|
|
Workers int
|
|
DNSConfigPath string
|
|
|
|
ViaSmartDNS bool
|
|
Mode DNSResolverMode
|
|
SmartDNSAddr string
|
|
SmartDNSWildcards []string
|
|
}
|
|
|
|
// EN: Aggregated resolver outputs consumed by routes update pipeline.
|
|
// RU: Агрегированные результаты резолвера, используемые пайплайном обновления маршрутов.
|
|
type resolverResult struct {
|
|
IPs []string
|
|
IPMap [][2]string
|
|
DirectIPs []string
|
|
DirectIPMap [][2]string
|
|
WildcardIPs []string
|
|
WildcardIPMap [][2]string
|
|
DomainCache map[string]any
|
|
PtrCache map[string]any
|
|
}
|
|
|
|
// EN: Runtime DNS upstream pools for standard and meta-special lookups.
|
|
// RU: Наборы DNS-апстримов для обычных и meta-special резолвов.
|
|
type dnsConfig struct {
|
|
Default []string
|
|
Meta []string
|
|
SmartDNS string
|
|
Mode DNSResolverMode
|
|
}
|