145 lines
4.7 KiB
Go
145 lines
4.7 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"time"
|
|
|
|
transportcfg "selective-vpn-api/app/transportcfg"
|
|
)
|
|
|
|
type transportDialRunner func(ctx context.Context, network, address string) (net.Conn, error)
|
|
|
|
var transportDialContext transportDialRunner = func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
var d net.Dialer
|
|
return d.DialContext(ctx, network, address)
|
|
}
|
|
|
|
type transportDialEndpoint struct {
|
|
Host string
|
|
Port int
|
|
}
|
|
|
|
func (ep transportDialEndpoint) address() string {
|
|
return transportcfg.Endpoint{Host: ep.Host, Port: ep.Port}.Address()
|
|
}
|
|
|
|
func transportProbeClientLatency(client TransportClient) (int, error) {
|
|
return transportcfg.ProbeClientLatency(transportCfgClient(client), transportProbeDeps())
|
|
}
|
|
|
|
func transportProbeDialEndpoint(client TransportClient, ep transportDialEndpoint, timeout time.Duration) (int, error) {
|
|
return transportcfg.ProbeDialEndpoint(
|
|
transportCfgClient(client),
|
|
transportcfg.Endpoint{Host: ep.Host, Port: ep.Port},
|
|
timeout,
|
|
transportProbeDeps(),
|
|
)
|
|
}
|
|
|
|
func transportProbeDialEndpointHost(ep transportDialEndpoint, timeout time.Duration) (int, error) {
|
|
return transportcfg.ProbeDialEndpointHost(
|
|
transportcfg.Endpoint{Host: ep.Host, Port: ep.Port},
|
|
timeout,
|
|
transportcfg.DialRunner(transportDialContext),
|
|
)
|
|
}
|
|
|
|
func transportProbeDialEndpointInNetns(client TransportClient, ep transportDialEndpoint, timeout time.Duration) (int, error) {
|
|
return transportcfg.ProbeDialEndpointInNetns(
|
|
transportCfgClient(client),
|
|
transportcfg.Endpoint{Host: ep.Host, Port: ep.Port},
|
|
timeout,
|
|
transportProbeDeps(),
|
|
)
|
|
}
|
|
|
|
func transportCollectProbeEndpoints(client TransportClient) []transportDialEndpoint {
|
|
return transportDialEndpointsFromCfg(transportcfg.CollectProbeEndpoints(transportCfgClient(client), nil, transportConfigInt))
|
|
}
|
|
|
|
func transportCollectConfigProbeEndpoints(cfg map[string]any) []transportDialEndpoint {
|
|
return transportDialEndpointsFromCfg(transportcfg.CollectConfigProbeEndpoints(cfg, transportConfigInt))
|
|
}
|
|
|
|
func transportCollectSingBoxConfigProbeEndpoints(client TransportClient) []transportDialEndpoint {
|
|
return transportDialEndpointsFromCfg(transportcfg.CollectSingBoxConfigProbeEndpoints(transportCfgClient(client), nil))
|
|
}
|
|
|
|
func transportCollectProbeEndpointsRecursive(node any, out *[]transportDialEndpoint) {
|
|
if out == nil {
|
|
return
|
|
}
|
|
tmp := make([]transportcfg.Endpoint, 0, len(*out))
|
|
for _, ep := range *out {
|
|
tmp = append(tmp, transportcfg.Endpoint{Host: ep.Host, Port: ep.Port})
|
|
}
|
|
transportcfg.CollectProbeEndpointsRecursive(node, &tmp)
|
|
*out = transportDialEndpointsFromCfg(tmp)
|
|
}
|
|
|
|
func transportParseDialEndpoint(raw string, fallbackPort int) (transportDialEndpoint, bool) {
|
|
ep, ok := transportcfg.ParseDialEndpoint(raw, fallbackPort)
|
|
if !ok {
|
|
return transportDialEndpoint{}, false
|
|
}
|
|
return transportDialEndpoint{Host: ep.Host, Port: ep.Port}, true
|
|
}
|
|
|
|
func transportDedupeProbeEndpoints(in []transportDialEndpoint) []transportDialEndpoint {
|
|
cfgIn := make([]transportcfg.Endpoint, 0, len(in))
|
|
for _, ep := range in {
|
|
cfgIn = append(cfgIn, transportcfg.Endpoint{Host: ep.Host, Port: ep.Port})
|
|
}
|
|
return transportDialEndpointsFromCfg(transportcfg.DedupeProbeEndpoints(cfgIn))
|
|
}
|
|
|
|
func transportParseInt(raw any) (int, bool) {
|
|
return transportcfg.ParseInt(raw)
|
|
}
|
|
|
|
func splitCSV(raw string) []string {
|
|
return transportcfg.SplitCSV(raw)
|
|
}
|
|
|
|
func transportProbeDeps() transportcfg.ProbeDeps {
|
|
return transportcfg.ProbeDeps{
|
|
Dial: transportcfg.DialRunner(transportDialContext),
|
|
HealthTimeout: transportBackendHealthTimeout,
|
|
ProbeTimeout: transportBackendProbeTimeout,
|
|
NetnsEnabled: func(c transportcfg.Client) bool {
|
|
return transportNetnsEnabled(transportClientFromCfg(c))
|
|
},
|
|
NetnsName: func(c transportcfg.Client) string {
|
|
return transportNetnsName(transportClientFromCfg(c))
|
|
},
|
|
NetnsExecCommand: func(c transportcfg.Client, ns string, command ...string) (string, []string, error) {
|
|
return transportNetnsExecCommand(transportClientFromCfg(c), ns, command...)
|
|
},
|
|
RunCommand: func(timeout time.Duration, name string, args ...string) (string, string, int, error) {
|
|
return transportRunCommand(timeout, name, args...)
|
|
},
|
|
CommandError: transportCommandError,
|
|
ShellJoinArgs: func(args []string) string {
|
|
return shellJoinArgs(args)
|
|
},
|
|
ConfigInt: transportConfigInt,
|
|
}
|
|
}
|
|
|
|
func transportClientFromCfg(client transportcfg.Client) TransportClient {
|
|
return TransportClient{
|
|
ID: client.ID,
|
|
Kind: TransportClientKind(client.Kind),
|
|
Config: cloneMap(client.Config),
|
|
}
|
|
}
|
|
|
|
func transportDialEndpointsFromCfg(in []transportcfg.Endpoint) []transportDialEndpoint {
|
|
out := make([]transportDialEndpoint, 0, len(in))
|
|
for _, ep := range in {
|
|
out = append(out, transportDialEndpoint{Host: ep.Host, Port: ep.Port})
|
|
}
|
|
return out
|
|
}
|