github.com/xxf098/lite-proxy@v0.15.1-0.20230422081941-12c69f323218/config/trojan.go (about)

     1  package config
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"net/url"
     7  	"strconv"
     8  
     9  	"github.com/xxf098/lite-proxy/outbound"
    10  )
    11  
    12  // type TrojanGoOption struct {
    13  // }
    14  
    15  // TODO: SkipCertVerify
    16  func TrojanLinkToTrojanOption(link string) (*outbound.TrojanOption, error) {
    17  	u, err := url.Parse(link)
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  	if u.Scheme != "trojan" {
    22  		return nil, errors.New("not a trojan link")
    23  	}
    24  	pass := u.User.Username()
    25  	hostport := u.Host
    26  	host, _, err := net.SplitHostPort(hostport)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	port, err := strconv.Atoi(u.Port())
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	// frag := u.Fragment
    35  	// fmt.Printf("password: %s, host: %s, port: %d, frag: %s\n", pass, host, port, frag)
    36  	trojanOption := outbound.TrojanOption{
    37  		Name:     "trojan",
    38  		Password: pass,
    39  		Port:     port,
    40  		Server:   host,
    41  		Remarks:  u.Fragment,
    42  		ALPN:     []string{"h2", "http/1.1"},
    43  	}
    44  	if rawQuery, err := url.ParseQuery(u.RawQuery); err == nil {
    45  		trojanOption.SNI = rawQuery.Get("sni")
    46  		trojanOption.SkipCertVerify = rawQuery.Get("allowInsecure") == "1"
    47  		network := rawQuery.Get("type")
    48  		if network == "ws" {
    49  			trojanOption.Network = "ws"
    50  			p := rawQuery.Get("path")
    51  			if len(p) > 0 {
    52  				wsOption := outbound.WSOptions{Path: p}
    53  				wsOption.Headers = map[string]string{}
    54  				host := rawQuery.Get("host")
    55  				if len(host) > 0 {
    56  					wsOption.Headers["host"] = host
    57  				}
    58  				Host := rawQuery.Get("Host")
    59  				if len(Host) > 0 {
    60  					wsOption.Headers["Host"] = Host
    61  				}
    62  				trojanOption.WSOpts = wsOption
    63  			}
    64  		}
    65  		if network == "grpc" {
    66  			trojanOption.Network = "grpc"
    67  			serviceName := rawQuery.Get("serviceName")
    68  			if len(serviceName) > 0 {
    69  				trojanOption.GrpcOpts = outbound.GrpcOptions{GrpcServiceName: serviceName}
    70  			}
    71  		}
    72  
    73  	}
    74  	if len(trojanOption.Remarks) < 1 {
    75  		trojanOption.Remarks = trojanOption.Server
    76  	}
    77  	return &trojanOption, nil
    78  }
    79  
    80  func init() {
    81  	outbound.RegisterDialerCreator("trojan", func(link string) (outbound.Dialer, error) {
    82  		trojanOption, err := TrojanLinkToTrojanOption(link)
    83  		if err != nil {
    84  			return nil, err
    85  		}
    86  		return outbound.NewTrojan(trojanOption)
    87  	})
    88  }