118 lines
3.7 KiB
Go
118 lines
3.7 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type transportIfaceBinding struct {
|
|
IfaceID string
|
|
Mode TransportInterfaceMode
|
|
RuntimeIface string
|
|
NetnsName string
|
|
RoutingTable string
|
|
}
|
|
|
|
func syncTransportInterfacesWithClientsLocked(clients []TransportClient) (transportInterfacesState, error) {
|
|
ifaces := loadTransportInterfacesState()
|
|
norm, changed := normalizeTransportInterfacesState(ifaces, clients)
|
|
if changed {
|
|
if err := saveTransportInterfacesState(norm); err != nil {
|
|
appendTraceLineRateLimited(
|
|
"transport",
|
|
fmt.Sprintf("interfaces sync warning: save failed: %v", err),
|
|
20*time.Second,
|
|
)
|
|
}
|
|
}
|
|
return norm, nil
|
|
}
|
|
|
|
func findTransportInterfaceByID(items []TransportInterface, ifaceID string) (TransportInterface, bool) {
|
|
id := normalizeTransportIfaceID(ifaceID)
|
|
for _, it := range items {
|
|
if normalizeTransportIfaceID(it.ID) == id {
|
|
return it, true
|
|
}
|
|
}
|
|
return TransportInterface{}, false
|
|
}
|
|
|
|
func resolveTransportIfaceBinding(client TransportClient, ifaces transportInterfacesState) transportIfaceBinding {
|
|
ifaceID := normalizeTransportIfaceID(client.IfaceID)
|
|
binding := transportIfaceBinding{
|
|
IfaceID: ifaceID,
|
|
Mode: normalizeTransportInterfaceMode("", ifaceID),
|
|
}
|
|
|
|
if iface, ok := findTransportInterfaceByID(ifaces.Items, ifaceID); ok {
|
|
binding.Mode = normalizeTransportInterfaceMode(iface.Mode, ifaceID)
|
|
binding.RuntimeIface = strings.TrimSpace(iface.RuntimeIface)
|
|
if strings.TrimSpace(iface.NetnsName) != "" {
|
|
binding.NetnsName = normalizeTransportNetnsName(strings.TrimSpace(iface.NetnsName), client.ID)
|
|
}
|
|
if hint := resolveTransportInterfaceRoutingTable(iface, ifaceID); strings.TrimSpace(hint) != "" {
|
|
binding.RoutingTable = hint
|
|
}
|
|
}
|
|
|
|
if strings.TrimSpace(binding.RuntimeIface) == "" {
|
|
binding.RuntimeIface = strings.TrimSpace(client.Iface)
|
|
}
|
|
|
|
if strings.TrimSpace(binding.RoutingTable) == "" {
|
|
if binding.IfaceID != transportDefaultIfaceID {
|
|
binding.RoutingTable = transportRoutingTableForIfaceID(binding.IfaceID)
|
|
} else {
|
|
binding.RoutingTable = normalizeTransportRoutingTable(client.RoutingTable, transportRoutingTableForID(client.ID))
|
|
}
|
|
}
|
|
|
|
if transportNetnsEnabled(client) {
|
|
explicit := strings.TrimSpace(transportConfigString(client.Config, "netns_name"))
|
|
if explicit != "" {
|
|
binding.NetnsName = transportNetnsName(client)
|
|
} else if strings.TrimSpace(binding.NetnsName) == "" {
|
|
if binding.IfaceID != transportDefaultIfaceID {
|
|
binding.NetnsName = normalizeTransportNetnsName("svpn-"+binding.IfaceID, client.ID)
|
|
} else {
|
|
binding.NetnsName = normalizeTransportNetnsName("svpn-"+sanitizeID(client.ID), client.ID)
|
|
}
|
|
}
|
|
}
|
|
return binding
|
|
}
|
|
|
|
func applyTransportIfaceBinding(client TransportClient, ifaces transportInterfacesState, now time.Time) (TransportClient, bool) {
|
|
updated := client
|
|
changed := false
|
|
binding := resolveTransportIfaceBinding(client, ifaces)
|
|
|
|
if updated.IfaceID != binding.IfaceID {
|
|
updated.IfaceID = binding.IfaceID
|
|
changed = true
|
|
}
|
|
if strings.TrimSpace(updated.Iface) == "" && strings.TrimSpace(binding.RuntimeIface) != "" {
|
|
updated.Iface = binding.RuntimeIface
|
|
changed = true
|
|
}
|
|
if strings.TrimSpace(binding.RoutingTable) != "" && strings.TrimSpace(updated.RoutingTable) != strings.TrimSpace(binding.RoutingTable) {
|
|
updated.RoutingTable = strings.TrimSpace(binding.RoutingTable)
|
|
changed = true
|
|
}
|
|
if transportNetnsEnabled(updated) && strings.TrimSpace(transportConfigString(updated.Config, "netns_name")) == "" && strings.TrimSpace(binding.NetnsName) != "" {
|
|
cfg := cloneMap(updated.Config)
|
|
if cfg == nil {
|
|
cfg = map[string]any{}
|
|
}
|
|
cfg["netns_name"] = binding.NetnsName
|
|
updated.Config = cfg
|
|
changed = true
|
|
}
|
|
if changed {
|
|
updated.UpdatedAt = now.Format(time.RFC3339)
|
|
}
|
|
return updated, changed
|
|
}
|