github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/node/parser/trojan.go (about)

     1  package parser
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/url"
     7  	"strconv"
     8  
     9  	"github.com/Asutorufa/yuhaiin/pkg/protos/node/point"
    10  	"github.com/Asutorufa/yuhaiin/pkg/protos/node/protocol"
    11  	"github.com/Asutorufa/yuhaiin/pkg/protos/node/subscribe"
    12  )
    13  
    14  func init() {
    15  	store.Store(subscribe.Type_trojan, func(data []byte) (*point.Point, error) {
    16  		u, err := url.Parse(string(data))
    17  		if err != nil {
    18  			return nil, fmt.Errorf("parse trojan link error: %w", err)
    19  		}
    20  
    21  		if u.Scheme != "trojan" {
    22  			return nil, errors.New("invalid scheme")
    23  		}
    24  		port, err := strconv.ParseUint(u.Port(), 10, 16)
    25  		if err != nil {
    26  			return nil, errors.New("invalid port")
    27  		}
    28  
    29  		var servername []string
    30  		if u.Query().Get("sni") != "" {
    31  			servername = []string{u.Query().Get("sni")}
    32  		}
    33  
    34  		p := &point.Point{
    35  			Name:   "[trojan]" + u.Fragment,
    36  			Origin: point.Origin_remote,
    37  			Protocols: []*protocol.Protocol{
    38  				{
    39  					Protocol: &protocol.Protocol_Simple{
    40  						Simple: &protocol.Simple{
    41  							Host: u.Hostname(),
    42  							Port: int32(port),
    43  						},
    44  					},
    45  				},
    46  				{
    47  					Protocol: &protocol.Protocol_Tls{
    48  						Tls: &protocol.TlsConfig{
    49  							Enable:      true,
    50  							ServerNames: servername,
    51  						},
    52  					},
    53  				},
    54  				{
    55  					Protocol: &protocol.Protocol_Trojan{
    56  						Trojan: &protocol.Trojan{
    57  							Password: u.User.String(),
    58  							Peer:     u.Query().Get("peer"),
    59  						},
    60  					},
    61  				},
    62  			},
    63  		}
    64  
    65  		return p, nil
    66  	})
    67  }