package link import ( "net/url" "strings" "github.com/sagernet/sing-box/common" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" ) func parseAnyTLSLink(link string) (option.Outbound, error) { linkURL, err := url.Parse(link) if err != nil { return option.Outbound{}, err } if linkURL.User == nil || linkURL.User.Username() == "" { return option.Outbound{}, E.New("missing password") } var options option.AnyTLSOutboundOptions TLSOptions := option.OutboundTLSOptions{ Enabled: true, ECH: &option.OutboundECHOptions{}, UTLS: &option.OutboundUTLSOptions{}, Reality: &option.OutboundRealityOptions{}, } options.Server = linkURL.Hostname() TLSOptions.ServerName = linkURL.Hostname() options.ServerPort = common.StringToType[uint16](linkURL.Port()) options.Password = linkURL.User.Username() proxy := map[string]string{} for key, values := range linkURL.Query() { value := values[0] proxy[key] = value } for key, value := range proxy { switch key { case "insecure": if value == "1" || value == "true" { TLSOptions.Insecure = true } case "sni": TLSOptions.ServerName = value case "alpn": TLSOptions.ALPN = strings.Split(value, ",") case "fp": TLSOptions.UTLS.Enabled = true TLSOptions.UTLS.Fingerprint = value case "tfo", "tcp-fast-open", "tcp_fast_open": if value == "1" || value == "true" { options.TCPFastOpen = true } } } outbound := option.Outbound{ Type: C.TypeAnyTLS, Tag: linkURL.Fragment, } options.TLS = &TLSOptions outbound.Options = &options return outbound, nil }