dae/component/outbound/dialer_selection_policy.go

69 lines
2.0 KiB
Go

/*
* SPDX-License-Identifier: AGPL-3.0-only
* Copyright (c) since 2023, mzz2017 <mzz@tuta.io>
*/
package outbound
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/v2rayA/dae/common/consts"
"github.com/v2rayA/dae/config"
"github.com/v2rayA/dae/pkg/config_parser"
"strconv"
)
type DialerSelectionPolicy struct {
Policy consts.DialerSelectionPolicy
FixedIndex int
}
func NewDialerSelectionPolicyFromGroupParam(param *config.GroupParam) (policy *DialerSelectionPolicy, err error) {
switch val := param.Policy.(type) {
case string:
switch consts.DialerSelectionPolicy(val) {
case consts.DialerSelectionPolicy_Random,
consts.DialerSelectionPolicy_MinAverage10Latencies,
consts.DialerSelectionPolicy_MinLastLatency:
return &DialerSelectionPolicy{
Policy: consts.DialerSelectionPolicy(val),
}, nil
case consts.DialerSelectionPolicy_Fixed:
return nil, fmt.Errorf("%v need to specify node index", val)
default:
return nil, fmt.Errorf("unexpected policy: %v", val)
}
case []*config_parser.Function:
if len(val) > 1 || len(val) == 0 {
logrus.Debugf("%@", val)
return nil, fmt.Errorf("policy should be exact 1 function: got %v", len(val))
}
f := val[0]
switch consts.DialerSelectionPolicy(f.Name) {
case consts.DialerSelectionPolicy_Fixed:
// Should be like:
// policy: fixed(0)
if f.Not {
return nil, fmt.Errorf("policy param does not support not operator: !%v()", f.Name)
}
if len(f.Params) > 1 || f.Params[0].Key != "" {
return nil, fmt.Errorf(`invalid "%v" param format`, f.Name)
}
strIndex := f.Params[0].Val
index, err := strconv.Atoi(strIndex)
if len(f.Params) > 1 || f.Params[0].Key != "" {
return nil, fmt.Errorf(`invalid "%v" param format: %w`, f.Name, err)
}
return &DialerSelectionPolicy{
Policy: consts.DialerSelectionPolicy(f.Name),
FixedIndex: index,
}, nil
default:
return nil, fmt.Errorf("unexpected policy func: %v", f.Name)
}
default:
return nil, fmt.Errorf("unexpected param.Policy.(type): %T", val)
}
}