|
1 | 1 | package engine |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "encoding/base64" |
5 | 4 | "fmt" |
6 | 5 | "net" |
7 | 6 | "net/netip" |
8 | 7 | "net/url" |
9 | 8 | "runtime" |
10 | 9 | "strings" |
11 | 10 |
|
12 | | - "github.com/gorilla/schema" |
13 | | - |
14 | 11 | "github.com/xjasonlyu/tun2socks/v2/core/device" |
15 | 12 | "github.com/xjasonlyu/tun2socks/v2/core/device/fdbased" |
16 | 13 | "github.com/xjasonlyu/tun2socks/v2/core/device/tun" |
17 | 14 | "github.com/xjasonlyu/tun2socks/v2/proxy" |
18 | | - "github.com/xjasonlyu/tun2socks/v2/proxy/proto" |
| 15 | +) |
| 16 | + |
| 17 | +const ( |
| 18 | + defaultDeviceType = "tun" |
| 19 | + defaultProxyType = "socks5" |
19 | 20 | ) |
20 | 21 |
|
21 | 22 | func parseRestAPI(s string) (*url.URL, error) { |
@@ -47,7 +48,7 @@ func parseRestAPI(s string) (*url.URL, error) { |
47 | 48 |
|
48 | 49 | func parseDevice(s string, mtu uint32) (device.Device, error) { |
49 | 50 | if !strings.Contains(s, "://") { |
50 | | - s = fmt.Sprintf("%s://%s", tun.Driver /* default driver */, s) |
| 51 | + s = fmt.Sprintf("%s://%s", defaultDeviceType, s) |
51 | 52 | } |
52 | 53 |
|
53 | 54 | u, err := url.Parse(s) |
@@ -79,111 +80,14 @@ func parseFD(u *url.URL, mtu uint32) (device.Device, error) { |
79 | 80 |
|
80 | 81 | func parseProxy(s string) (proxy.Proxy, error) { |
81 | 82 | if !strings.Contains(s, "://") { |
82 | | - s = fmt.Sprintf("%s://%s", proto.Socks5 /* default protocol */, s) |
| 83 | + s = fmt.Sprintf("%s://%s", defaultProxyType, s) |
83 | 84 | } |
84 | 85 |
|
85 | 86 | u, err := url.Parse(s) |
86 | 87 | if err != nil { |
87 | 88 | return nil, err |
88 | 89 | } |
89 | | - |
90 | | - protocol := strings.ToLower(u.Scheme) |
91 | | - |
92 | | - switch protocol { |
93 | | - case proto.Direct.String(): |
94 | | - return proxy.NewDirect(), nil |
95 | | - case proto.Reject.String(): |
96 | | - return proxy.NewReject(), nil |
97 | | - case proto.HTTP.String(): |
98 | | - return parseHTTP(u) |
99 | | - case proto.Socks4.String(): |
100 | | - return parseSocks4(u) |
101 | | - case proto.Socks5.String(): |
102 | | - return parseSocks5(u) |
103 | | - case proto.Shadowsocks.String(): |
104 | | - return parseShadowsocks(u) |
105 | | - case proto.Relay.String(): |
106 | | - return parseRelay(u) |
107 | | - default: |
108 | | - return nil, fmt.Errorf("unsupported protocol: %s", protocol) |
109 | | - } |
110 | | -} |
111 | | - |
112 | | -func parseHTTP(u *url.URL) (proxy.Proxy, error) { |
113 | | - address, username := u.Host, u.User.Username() |
114 | | - password, _ := u.User.Password() |
115 | | - return proxy.NewHTTP(address, username, password) |
116 | | -} |
117 | | - |
118 | | -func parseSocks4(u *url.URL) (proxy.Proxy, error) { |
119 | | - address, userID := u.Host, u.User.Username() |
120 | | - return proxy.NewSocks4(address, userID) |
121 | | -} |
122 | | - |
123 | | -func parseSocks5(u *url.URL) (proxy.Proxy, error) { |
124 | | - address, username := u.Host, u.User.Username() |
125 | | - password, _ := u.User.Password() |
126 | | - |
127 | | - // Socks5 over UDS |
128 | | - if address == "" { |
129 | | - address = u.Path |
130 | | - } |
131 | | - return proxy.NewSocks5(address, username, password) |
132 | | -} |
133 | | - |
134 | | -func parseShadowsocks(u *url.URL) (proxy.Proxy, error) { |
135 | | - var ( |
136 | | - address = u.Host |
137 | | - method, password string |
138 | | - obfsMode, obfsHost string |
139 | | - ) |
140 | | - |
141 | | - if ss := u.User.String(); ss == "" { |
142 | | - method = "dummy" // none cipher mode |
143 | | - } else if pass, set := u.User.Password(); set { |
144 | | - method = u.User.Username() |
145 | | - password = pass |
146 | | - } else { |
147 | | - data, _ := base64.RawURLEncoding.DecodeString(ss) |
148 | | - userInfo := strings.SplitN(string(data), ":", 2) |
149 | | - if len(userInfo) == 2 { |
150 | | - method = userInfo[0] |
151 | | - password = userInfo[1] |
152 | | - } |
153 | | - } |
154 | | - |
155 | | - rawQuery, _ := url.QueryUnescape(u.RawQuery) |
156 | | - for _, s := range strings.Split(rawQuery, ";") { |
157 | | - data := strings.SplitN(s, "=", 2) |
158 | | - if len(data) != 2 { |
159 | | - continue |
160 | | - } |
161 | | - key := data[0] |
162 | | - value := data[1] |
163 | | - |
164 | | - switch key { |
165 | | - case "obfs": |
166 | | - obfsMode = value |
167 | | - case "obfs-host": |
168 | | - obfsHost = value |
169 | | - } |
170 | | - } |
171 | | - |
172 | | - return proxy.NewShadowsocks(address, method, password, obfsMode, obfsHost) |
173 | | -} |
174 | | - |
175 | | -func parseRelay(u *url.URL) (proxy.Proxy, error) { |
176 | | - address, username := u.Host, u.User.Username() |
177 | | - password, _ := u.User.Password() |
178 | | - |
179 | | - opts := struct { |
180 | | - NoDelay bool |
181 | | - }{} |
182 | | - if err := schema.NewDecoder().Decode(&opts, u.Query()); err != nil { |
183 | | - return nil, err |
184 | | - } |
185 | | - |
186 | | - return proxy.NewRelay(address, username, password, opts.NoDelay) |
| 90 | + return proxy.Parse(u) |
187 | 91 | } |
188 | 92 |
|
189 | 93 | func parseMulticastGroups(s string) (multicastGroups []netip.Addr, _ error) { |
|
0 commit comments