From e89c70dd85af523dc520eaf7526cec83b659c222 Mon Sep 17 00:00:00 2001 From: nite07 Date: Wed, 13 Nov 2024 10:49:01 +0800 Subject: [PATCH] feat: add socks parser --- constant/prefix.go | 1 + parser/parsers_map.go | 1 + parser/socks.go | 87 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 parser/socks.go diff --git a/constant/prefix.go b/constant/prefix.go index 9a27b85..bb0aa82 100755 --- a/constant/prefix.go +++ b/constant/prefix.go @@ -8,4 +8,5 @@ const ( TrojanPrefix string = "trojan://" VLESSPrefix string = "vless://" VMessPrefix string = "vmess://" + SocksPrefix string = "socks" ) diff --git a/parser/parsers_map.go b/parser/parsers_map.go index d17c8ac..f731da3 100755 --- a/parser/parsers_map.go +++ b/parser/parsers_map.go @@ -13,4 +13,5 @@ var ParserMap map[string]func(string) (model.Outbound, error) = map[string]func( constant.HysteriaPrefix: ParseHysteria, constant.Hysteria2Prefix1: ParseHysteria2, constant.Hysteria2Prefix2: ParseHysteria2, + constant.SocksPrefix: ParseSocks, } diff --git a/parser/socks.go b/parser/socks.go new file mode 100644 index 0000000..76ef89e --- /dev/null +++ b/parser/socks.go @@ -0,0 +1,87 @@ +package parser + +import ( + "fmt" + "net/url" + "strings" + + "github.com/nitezs/sub2sing-box/constant" + "github.com/nitezs/sub2sing-box/model" + "github.com/nitezs/sub2sing-box/util" + "github.com/sagernet/sing-box/option" +) + +func ParseSocks(proxy string) (model.Outbound, error) { + if !strings.HasPrefix(proxy, constant.SocksPrefix) { + return model.Outbound{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy} + } + link, err := url.Parse(proxy) + if err != nil { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "url parse error", + Raw: proxy, + } + } + server := link.Hostname() + if server == "" { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "missing server host", + Raw: proxy, + } + } + portStr := link.Port() + if portStr == "" { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "missing server port", + Raw: proxy, + } + } + port, err := ParsePort(portStr) + if err != nil { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidPort, + Raw: portStr, + } + } + + remarks := link.Fragment + if remarks == "" { + remarks = fmt.Sprintf("%s:%s", server, portStr) + } + remarks = strings.TrimSpace(remarks) + + encodeStr := link.User.Username() + var username, password string + if encodeStr != "" { + decodeStr, err := util.DecodeBase64(encodeStr) + splitStr := strings.Split(decodeStr, ":") + if err != nil { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "url parse error", + Raw: proxy, + } + } + username = splitStr[0] + if len(splitStr) == 2 { + password = splitStr[1] + } + } + return model.Outbound{ + Outbound: option.Outbound{ + Type: "socks", + Tag: remarks, + SocksOptions: option.SocksOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: server, + ServerPort: port, + }, + Username: username, + Password: password, + }, + }, + }, nil +}