mirror of
https://github.com/nadoo/glider.git
synced 2026-07-17 17:30:11 +08:00
This commit is contained in:
parent
38b34030bc
commit
579b427e9d
2
go.mod
2
go.mod
@ -13,7 +13,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
|
||||
github.com/klauspost/reedsolomon v1.14.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.27 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@ -29,8 +29,8 @@ github.com/insomniacslk/dhcp v0.0.0-20260603135910-a415979eb11e h1:7j1+lOuGBg7PQ
|
||||
github.com/insomniacslk/dhcp v0.0.0-20260603135910-a415979eb11e/go.mod h1:qfvBmyDNp+/liLEYWRvqny/PEz9hGe2Dz833eXILSmo=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
|
||||
github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
|
||||
github.com/klauspost/reedsolomon v1.14.1 h1:swE9kzyWXD/wVG+l5Pe8bWnQ0giIY7D1GjCBKk3kG2U=
|
||||
github.com/klauspost/reedsolomon v1.14.1/go.mod h1:yjqqjgMTQkBUHSG97/rm4zipffCNbCiZcB3kTqr++sQ=
|
||||
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
|
||||
|
||||
@ -3,7 +3,7 @@ package proxy
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -59,7 +59,7 @@ func DialerFromURL(s string, dialer Dialer) (Dialer, error) {
|
||||
s = s + "://"
|
||||
}
|
||||
|
||||
scheme := s[:strings.Index(s, ":")]
|
||||
scheme, _, _ := strings.Cut(s, ":")
|
||||
c, ok := dialerCreators[strings.ToLower(scheme)]
|
||||
if ok {
|
||||
return c(s, dialer)
|
||||
@ -74,6 +74,6 @@ func DialerSchemes() string {
|
||||
for name := range dialerCreators {
|
||||
s = append(s, name)
|
||||
}
|
||||
sort.Strings(s)
|
||||
slices.Sort(s)
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
@ -60,13 +60,15 @@ func NewHTTP(s string, d proxy.Dialer, p proxy.Proxy) (*HTTP, error) {
|
||||
|
||||
// parseStartLine parses "GET /foo HTTP/1.1" OR "HTTP/1.1 200 OK" into its three parts.
|
||||
func parseStartLine(line string) (r1, r2, r3 string, ok bool) {
|
||||
s1 := strings.Index(line, " ")
|
||||
s2 := strings.Index(line[s1+1:], " ")
|
||||
if s1 < 0 || s2 < 0 {
|
||||
r1, rest, ok := strings.Cut(line, " ")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
s2 += s1 + 1
|
||||
return line[:s1], line[s1+1 : s2], line[s2+1:], true
|
||||
r2, r3, ok = strings.Cut(rest, " ")
|
||||
if !ok {
|
||||
return "", "", "", false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func cleanHeaders(header textproto.MIMEHeader) {
|
||||
@ -95,22 +97,23 @@ func writeHeaders(w io.Writer, header textproto.MIMEHeader) {
|
||||
}
|
||||
|
||||
func extractUserPass(auth string) (username, password string, ok bool) {
|
||||
if !strings.HasPrefix(auth, "Basic ") {
|
||||
token, ok := strings.CutPrefix(auth, "Basic ")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
|
||||
b, err := base64.StdEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s := string(b)
|
||||
idx := strings.IndexByte(s, ':')
|
||||
if idx < 0 {
|
||||
username, password, ok = strings.Cut(s, ":")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
return s[:idx], s[idx+1:], true
|
||||
return username, password, true
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@ -3,7 +3,7 @@ package proxy
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -44,7 +44,7 @@ func ServerFromURL(s string, proxy Proxy) (Server, error) {
|
||||
s = "mixed://" + s
|
||||
}
|
||||
|
||||
scheme := s[:strings.Index(s, ":")]
|
||||
scheme, _, _ := strings.Cut(s, ":")
|
||||
c, ok := serverCreators[strings.ToLower(scheme)]
|
||||
if ok {
|
||||
return c(s, proxy)
|
||||
@ -59,6 +59,6 @@ func ServerSchemes() string {
|
||||
for name := range serverCreators {
|
||||
s = append(s, name)
|
||||
}
|
||||
sort.Strings(s)
|
||||
slices.Sort(s)
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
@ -33,8 +33,7 @@ func sealVMessAEADHeader(key [16]byte, data []byte) []byte {
|
||||
connectionNonce := make([]byte, 8)
|
||||
rand.Read(connectionNonce)
|
||||
|
||||
aeadPayloadLengthSerializedByte := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(aeadPayloadLengthSerializedByte, uint16(len(data)))
|
||||
aeadPayloadLengthSerializedByte := binary.BigEndian.AppendUint16(nil, uint16(len(data)))
|
||||
|
||||
var payloadHeaderLengthAEADEncrypted []byte
|
||||
|
||||
|
||||
@ -93,13 +93,15 @@ func NewWS(s string, d proxy.Dialer, p proxy.Proxy, withTLS bool) (*WS, error) {
|
||||
// parseFirstLine parses "GET /foo HTTP/1.1" OR "HTTP/1.1 200 OK" into its three parts.
|
||||
// TODO: move to separate http lib package for reuse(also for http proxy module)
|
||||
func parseFirstLine(line string) (r1, r2, r3 string, ok bool) {
|
||||
s1 := strings.Index(line, " ")
|
||||
s2 := strings.Index(line[s1+1:], " ")
|
||||
if s1 < 0 || s2 < 0 {
|
||||
r1, rest, ok := strings.Cut(line, " ")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
s2 += s1 + 1
|
||||
return line[:s1], line[s1+1 : s2], line[s2+1:], true
|
||||
r2, r3, ok = strings.Cut(rest, " ")
|
||||
if !ok {
|
||||
return "", "", "", false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func generateClientKey() string {
|
||||
|
||||
@ -33,9 +33,9 @@ type Forwarder struct {
|
||||
func ForwarderFromURL(s, intface string, dialTimeout, relayTimeout time.Duration) (f *Forwarder, err error) {
|
||||
f = &Forwarder{url: s}
|
||||
|
||||
ss := strings.Split(s, "#")
|
||||
if len(ss) > 1 {
|
||||
err = f.parseOption(ss[1])
|
||||
chain, option, found := strings.Cut(s, "#")
|
||||
if found {
|
||||
err = f.parseOption(option)
|
||||
}
|
||||
|
||||
iface := intface
|
||||
@ -50,7 +50,7 @@ func ForwarderFromURL(s, intface string, dialTimeout, relayTimeout time.Duration
|
||||
}
|
||||
|
||||
var addrs []string
|
||||
for _, url := range strings.Split(ss[0], ",") {
|
||||
for url := range strings.SplitSeq(chain, ",") {
|
||||
d, err = proxy.DialerFromURL(url, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@ -16,18 +16,11 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// forwarder slice orderd by priority.
|
||||
type priSlice []*Forwarder
|
||||
|
||||
func (p priSlice) Len() int { return len(p) }
|
||||
func (p priSlice) Less(i, j int) bool { return p[i].Priority() > p[j].Priority() }
|
||||
func (p priSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// FwdrGroup is a forwarder group.
|
||||
type FwdrGroup struct {
|
||||
name string
|
||||
config *Strategy
|
||||
fwdrs priSlice
|
||||
fwdrs []*Forwarder
|
||||
avail []*Forwarder // available forwarders
|
||||
mu sync.RWMutex
|
||||
index uint32
|
||||
@ -66,7 +59,16 @@ func NewFwdrGroup(rulePath string, s []string, c *Strategy) *FwdrGroup {
|
||||
// newFwdrGroup returns a new FwdrGroup.
|
||||
func newFwdrGroup(name string, fwdrs []*Forwarder, c *Strategy) *FwdrGroup {
|
||||
p := &FwdrGroup{name: name, fwdrs: fwdrs, config: c}
|
||||
sort.Sort(p.fwdrs)
|
||||
slices.SortFunc(p.fwdrs, func(a, b *Forwarder) int {
|
||||
switch {
|
||||
case a.Priority() > b.Priority():
|
||||
return -1
|
||||
case a.Priority() < b.Priority():
|
||||
return 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
})
|
||||
|
||||
p.init()
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ func NewProxy(mainForwarders []string, mainStrategy *Strategy, rules []*Config)
|
||||
// if there's any forwarder defined in main config, make sure they will be accessed directly.
|
||||
if len(mainForwarders) > 0 {
|
||||
for _, f := range rd.main.fwdrs {
|
||||
addr := strings.Split(f.addr, ",")[0]
|
||||
addr, _, _ := strings.Cut(f.addr, ",")
|
||||
host, _, _ := net.SplitHostPort(addr)
|
||||
if _, err := netip.ParseAddr(host); err != nil {
|
||||
rd.domainMap.Store(strings.ToLower(host), direct)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user