mirror of https://github.com/ginuerzh/gost
15 changed files with 386 additions and 214 deletions
@ -1,139 +0,0 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"bufio" |
|||
"net" |
|||
"net/url" |
|||
"os" |
|||
"strings" |
|||
|
|||
"github.com/ginuerzh/gost/gost" |
|||
"github.com/go-log/log" |
|||
) |
|||
|
|||
type node struct { |
|||
Addr string |
|||
Protocol string // protocol: http/socks5/ss
|
|||
Transport string // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp
|
|||
Remote string // remote address, used by tcp/udp port forwarding
|
|||
Users []*url.Userinfo // authentication for proxy
|
|||
Whitelist *gost.Permissions |
|||
Blacklist *gost.Permissions |
|||
values url.Values |
|||
serverName string |
|||
} |
|||
|
|||
func parseNode(s string) (n node, err error) { |
|||
if !strings.Contains(s, "://") { |
|||
s = "gost://" + s |
|||
} |
|||
u, err := url.Parse(s) |
|||
if err != nil { |
|||
return |
|||
} |
|||
|
|||
query := u.Query() |
|||
|
|||
n = node{ |
|||
Addr: u.Host, |
|||
} |
|||
|
|||
if query.Get("whitelist") != "" { |
|||
if n.Whitelist, err = gost.ParsePermissions(query.Get("whitelist")); err != nil { |
|||
return |
|||
} |
|||
} else { |
|||
// By default allow for everyting
|
|||
n.Whitelist, _ = gost.ParsePermissions("*:*:*") |
|||
} |
|||
|
|||
if query.Get("blacklist") != "" { |
|||
if n.Blacklist, err = gost.ParsePermissions(query.Get("blacklist")); err != nil { |
|||
return |
|||
} |
|||
} else { |
|||
// By default block nothing
|
|||
n.Blacklist, _ = gost.ParsePermissions("") |
|||
} |
|||
|
|||
if u.User != nil { |
|||
n.Users = append(n.Users, u.User) |
|||
} |
|||
|
|||
users, er := parseUsers(n.values.Get("secrets")) |
|||
if users != nil { |
|||
n.Users = append(n.Users, users...) |
|||
} |
|||
if er != nil { |
|||
log.Log("load secrets:", er) |
|||
} |
|||
|
|||
if strings.Contains(u.Host, ":") { |
|||
n.serverName, _, _ = net.SplitHostPort(u.Host) |
|||
if n.serverName == "" { |
|||
n.serverName = "localhost" // default server name
|
|||
} |
|||
} |
|||
|
|||
schemes := strings.Split(u.Scheme, "+") |
|||
if len(schemes) == 1 { |
|||
n.Protocol = schemes[0] |
|||
n.Transport = schemes[0] |
|||
} |
|||
if len(schemes) == 2 { |
|||
n.Protocol = schemes[0] |
|||
n.Transport = schemes[1] |
|||
} |
|||
|
|||
switch n.Transport { |
|||
case "ws", "wss", "tls", "h2", "h2c", "quic", "kcp", "redirect", "ssu", "ssh": |
|||
case "https": |
|||
n.Protocol = "http" |
|||
n.Transport = "tls" |
|||
case "http2": // http2 -> http2+tls, h2c mode is http2+tcp
|
|||
n.Protocol = "http2" |
|||
n.Transport = "tls" |
|||
case "tcp", "udp": // started from v2.1, tcp and udp are for local port forwarding
|
|||
n.Remote = strings.Trim(u.EscapedPath(), "/") |
|||
case "rtcp", "rudp": // rtcp and rudp are for remote port forwarding
|
|||
n.Remote = strings.Trim(u.EscapedPath(), "/") |
|||
default: |
|||
n.Transport = "" |
|||
} |
|||
|
|||
switch n.Protocol { |
|||
case "http", "http2", "socks", "socks4", "socks4a", "socks5", "ss": |
|||
default: |
|||
n.Protocol = "" |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
func parseUsers(s string) (users []*url.Userinfo, err error) { |
|||
if s == "" { |
|||
return |
|||
} |
|||
|
|||
f, err := os.Open(s) |
|||
if err != nil { |
|||
return |
|||
} |
|||
scanner := bufio.NewScanner(f) |
|||
for scanner.Scan() { |
|||
line := strings.TrimSpace(scanner.Text()) |
|||
if line == "" || strings.HasPrefix(line, "#") { |
|||
continue |
|||
} |
|||
|
|||
s := strings.SplitN(line, " ", 2) |
|||
if len(s) == 1 { |
|||
users = append(users, url.User(strings.TrimSpace(s[0]))) |
|||
} else if len(s) == 2 { |
|||
users = append(users, url.UserPassword(strings.TrimSpace(s[0]), strings.TrimSpace(s[1]))) |
|||
} |
|||
} |
|||
|
|||
err = scanner.Err() |
|||
return |
|||
} |
|||
Loading…
Reference in new issue