github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/node/parser/shadowsocksr.go (about) 1 package parser 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "errors" 7 "log/slog" 8 "net/url" 9 "strconv" 10 "strings" 11 12 "github.com/Asutorufa/yuhaiin/pkg/log" 13 "github.com/Asutorufa/yuhaiin/pkg/protos/node/point" 14 "github.com/Asutorufa/yuhaiin/pkg/protos/node/protocol" 15 "github.com/Asutorufa/yuhaiin/pkg/protos/node/subscribe" 16 "github.com/Asutorufa/yuhaiin/pkg/utils/yerror" 17 ) 18 19 func init() { 20 store.Store(subscribe.Type_shadowsocksr, func(data []byte) (*point.Point, error) { 21 data = bytes.TrimPrefix(data, []byte("ssr://")) 22 dst := make([]byte, base64.RawStdEncoding.DecodedLen(len(data))) 23 _, err := base64.RawURLEncoding.Decode(dst, data) 24 if err != nil { 25 log.Warn("parse shadowsocksr failed", slog.String("data", string(data)), slog.Any("err", err)) 26 } 27 // ParseLink parse a base64 encode ssr link 28 decodeStr := bytes.Split(dst, []byte{'/', '?'}) 29 30 x := strings.Split(string(decodeStr[0]), ":") 31 if len(x) != 6 { 32 return nil, errors.New("link: " + string(decodeStr[0]) + " is not shadowsocksr link") 33 } 34 if len(decodeStr) <= 1 { 35 decodeStr = append(decodeStr, []byte{}) 36 } 37 query, _ := url.ParseQuery(string(decodeStr[1])) 38 39 port, err := strconv.ParseUint(x[1], 10, 16) 40 if err != nil { 41 return nil, errors.New("invalid port") 42 } 43 44 password, err := base64.RawURLEncoding.DecodeString(x[5]) 45 if err != nil { 46 log.Warn("parse shadowsocksr password failed", "err", err) 47 } 48 49 return &point.Point{ 50 Origin: point.Origin_remote, 51 Name: "[ssr]" + string(yerror.Ignore(base64.RawURLEncoding.DecodeString(query.Get("remarks")))), 52 Protocols: []*protocol.Protocol{ 53 { 54 Protocol: &protocol.Protocol_Simple{ 55 Simple: &protocol.Simple{ 56 Host: x[0], 57 Port: int32(port), 58 }, 59 }, 60 }, 61 { 62 Protocol: &protocol.Protocol_Shadowsocksr{ 63 Shadowsocksr: &protocol.Shadowsocksr{ 64 Server: x[0], 65 Port: x[1], 66 Protocol: x[2], 67 Method: x[3], 68 Obfs: x[4], 69 Password: string(password), 70 Obfsparam: string(yerror.Ignore(base64.RawURLEncoding.DecodeString(query.Get("obfsparam")))), 71 Protoparam: string(yerror.Ignore(base64.RawURLEncoding.DecodeString(query.Get("protoparam")))), 72 }, 73 }, 74 }, 75 }, 76 }, nil 77 }) 78 }