You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
1.9 KiB

4 years ago
package engine
import (
"encoding/base64"
4 years ago
"fmt"
"net/url"
"strings"
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/proxy"
)
func parseDevice(s string, mtu uint32) (device.Device, error) {
const defaultDriver = "tun"
if !strings.Contains(s, "://") {
s = defaultDriver + "://" + s
}
u, err := url.Parse(s)
if err != nil {
return nil, err
}
var d device.Device
driver := strings.ToLower(u.Scheme)
4 years ago
switch driver {
case "tun":
d, err = openTUN(u, mtu)
4 years ago
default:
err = fmt.Errorf("unsupported driver: %s", driver)
}
if err != nil {
return nil, err
}
return d, nil
}
func parseProxy(s string) (proxy.Proxy, error) {
4 years ago
const defaultProto = "socks5"
if !strings.Contains(s, "://") {
s = defaultProto + "://" + s
}
u, err := url.Parse(s)
if err != nil {
return nil, err
}
proto := strings.ToLower(u.Scheme)
switch proto {
case "direct":
return proxy.NewDirect(), nil
case "socks5":
return proxy.NewSocks5(parseSocks(u))
case "ss":
return proxy.NewShadowsocks(parseShadowsocks(u))
4 years ago
}
return nil, fmt.Errorf("unsupported protocol: %s", proto)
}
func parseSocks(u *url.URL) (address, username, password string) {
address = u.Host
username = u.User.Username()
password, _ = u.User.Password()
return
}
func parseShadowsocks(u *url.URL) (address, method, password, obfsMode, obfsHost string) {
address = u.Host
if pass, set := u.User.Password(); set {
method = u.User.Username()
password = pass
} else {
data, _ := base64.RawURLEncoding.DecodeString(u.User.String())
userInfo := strings.SplitN(string(data), ":", 2)
method = userInfo[0]
password = userInfo[1]
}
rawQuery, _ := url.QueryUnescape(u.RawQuery)
for _, s := range strings.Split(rawQuery, ";") {
data := strings.SplitN(s, "=", 2)
if len(data) != 2 {
continue
}
key := data[0]
value := data[1]
switch key {
case "obfs":
obfsMode = value
case "obfs-host":
obfsHost = value
}
}
return
}