Chore: pass staticcheck
This commit is contained in:
parent
c1b4382fe8
commit
5805334ccd
31 changed files with 72 additions and 99 deletions
|
@ -13,10 +13,6 @@ import (
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
defaultURLTestTimeout = time.Second * 5
|
|
||||||
)
|
|
||||||
|
|
||||||
type Base struct {
|
type Base struct {
|
||||||
name string
|
name string
|
||||||
addr string
|
addr string
|
||||||
|
|
|
@ -11,11 +11,13 @@ func ParseProxy(mapping map[string]interface{}) (C.Proxy, error) {
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
||||||
proxyType, existType := mapping["type"].(string)
|
proxyType, existType := mapping["type"].(string)
|
||||||
if !existType {
|
if !existType {
|
||||||
return nil, fmt.Errorf("Missing type")
|
return nil, fmt.Errorf("missing type")
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxy C.ProxyAdapter
|
var (
|
||||||
err := fmt.Errorf("Cannot parse")
|
proxy C.ProxyAdapter
|
||||||
|
err error
|
||||||
|
)
|
||||||
switch proxyType {
|
switch proxyType {
|
||||||
case "ss":
|
case "ss":
|
||||||
ssOption := &ShadowSocksOption{}
|
ssOption := &ShadowSocksOption{}
|
||||||
|
@ -72,7 +74,7 @@ func ParseProxy(mapping map[string]interface{}) (C.Proxy, error) {
|
||||||
}
|
}
|
||||||
proxy, err = NewTrojan(*trojanOption)
|
proxy, err = NewTrojan(*trojanOption)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Unsupport proxy type: %s", proxyType)
|
return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
var (
|
var (
|
||||||
errFormat = errors.New("format error")
|
errFormat = errors.New("format error")
|
||||||
errType = errors.New("unsupport type")
|
errType = errors.New("unsupport type")
|
||||||
errMissUse = errors.New("`use` field should not be empty")
|
|
||||||
errMissProxy = errors.New("`use` or `proxies` missing")
|
errMissProxy = errors.New("`use` or `proxies` missing")
|
||||||
errMissHealthCheck = errors.New("`url` or `interval` missing")
|
errMissHealthCheck = errors.New("`url` or `interval` missing")
|
||||||
errDuplicateProvider = errors.New("`duplicate provider name")
|
errDuplicateProvider = errors.New("`duplicate provider name")
|
||||||
|
@ -63,6 +62,10 @@ func ParseProxyGroup(config map[string]interface{}, proxyMap map[string]C.Proxy,
|
||||||
|
|
||||||
providers = append(providers, pd)
|
providers = append(providers, pd)
|
||||||
} else {
|
} else {
|
||||||
|
if _, ok := providersMap[groupName]; ok {
|
||||||
|
return nil, errDuplicateProvider
|
||||||
|
}
|
||||||
|
|
||||||
// select don't need health check
|
// select don't need health check
|
||||||
if groupOption.Type == "select" || groupOption.Type == "relay" {
|
if groupOption.Type == "select" || groupOption.Type == "relay" {
|
||||||
hc := provider.NewHealthCheck(ps, "", 0)
|
hc := provider.NewHealthCheck(ps, "", 0)
|
||||||
|
|
|
@ -22,7 +22,7 @@ type Relay struct {
|
||||||
func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||||
proxies := r.proxies(metadata)
|
proxies := r.proxies(metadata)
|
||||||
if len(proxies) == 0 {
|
if len(proxies) == 0 {
|
||||||
return nil, errors.New("Proxy does not exist")
|
return nil, errors.New("proxy does not exist")
|
||||||
}
|
}
|
||||||
first := proxies[0]
|
first := proxies[0]
|
||||||
last := proxies[len(proxies)-1]
|
last := proxies[len(proxies)-1]
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (s *Selector) Set(name string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("Proxy does not exist")
|
return errors.New("proxy not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selector) Unwrap(metadata *C.Metadata) C.Proxy {
|
func (s *Selector) Unwrap(metadata *C.Metadata) C.Proxy {
|
||||||
|
|
|
@ -120,20 +120,20 @@ func proxiesParse(buf []byte) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if schema.Proxies == nil {
|
if schema.Proxies == nil {
|
||||||
return nil, errors.New("File must have a `proxies` field")
|
return nil, errors.New("file must have a `proxies` field")
|
||||||
}
|
}
|
||||||
|
|
||||||
proxies := []C.Proxy{}
|
proxies := []C.Proxy{}
|
||||||
for idx, mapping := range schema.Proxies {
|
for idx, mapping := range schema.Proxies {
|
||||||
proxy, err := outbound.ParseProxy(mapping)
|
proxy, err := outbound.ParseProxy(mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Proxy %d error: %w", idx, err)
|
return nil, fmt.Errorf("proxy %d error: %w", idx, err)
|
||||||
}
|
}
|
||||||
proxies = append(proxies, proxy)
|
proxies = append(proxies, proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(proxies) == 0 {
|
if len(proxies) == 0 {
|
||||||
return nil, errors.New("File doesn't have any valid proxy")
|
return nil, errors.New("file doesn't have any valid proxy")
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxies, nil
|
return proxies, nil
|
||||||
|
|
|
@ -55,6 +55,8 @@ func (alloc *Allocator) Put(buf []byte) error {
|
||||||
if cap(buf) == 0 || cap(buf) > 65536 || cap(buf) != 1<<bits {
|
if cap(buf) == 0 || cap(buf) > 65536 || cap(buf) != 1<<bits {
|
||||||
return errors.New("allocator Put() incorrect buffer size")
|
return errors.New("allocator Put() incorrect buffer size")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lint:ignore SA6002 ignore temporarily
|
||||||
alloc.buffers[bits].Put(buf)
|
alloc.buffers[bits].Put(buf)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,11 @@ func TestAllocGet(t *testing.T) {
|
||||||
func TestAllocPut(t *testing.T) {
|
func TestAllocPut(t *testing.T) {
|
||||||
alloc := NewAllocator()
|
alloc := NewAllocator()
|
||||||
assert.NotNil(t, alloc.Put(nil), "put nil misbehavior")
|
assert.NotNil(t, alloc.Put(nil), "put nil misbehavior")
|
||||||
assert.NotNil(t, alloc.Put(make([]byte, 3, 3)), "put elem:3 []bytes misbehavior")
|
assert.NotNil(t, alloc.Put(make([]byte, 3)), "put elem:3 []bytes misbehavior")
|
||||||
assert.Nil(t, alloc.Put(make([]byte, 4, 4)), "put elem:4 []bytes misbehavior")
|
assert.Nil(t, alloc.Put(make([]byte, 4)), "put elem:4 []bytes misbehavior")
|
||||||
assert.Nil(t, alloc.Put(make([]byte, 1023, 1024)), "put elem:1024 []bytes misbehavior")
|
assert.Nil(t, alloc.Put(make([]byte, 1023, 1024)), "put elem:1024 []bytes misbehavior")
|
||||||
assert.Nil(t, alloc.Put(make([]byte, 65536, 65536)), "put elem:65536 []bytes misbehavior")
|
assert.Nil(t, alloc.Put(make([]byte, 65536)), "put elem:65536 []bytes misbehavior")
|
||||||
assert.NotNil(t, alloc.Put(make([]byte, 65537, 65537)), "put elem:65537 []bytes misbehavior")
|
assert.NotNil(t, alloc.Put(make([]byte, 65537)), "put elem:65537 []bytes misbehavior")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAllocPutThenGet(t *testing.T) {
|
func TestAllocPutThenGet(t *testing.T) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ type Result struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do single.Do likes sync.singleFilght
|
||||||
|
//lint:ignore ST1008 it likes sync.singleFilght
|
||||||
func (s *Single) Do(fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
|
func (s *Single) Do(fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
|
||||||
s.mux.Lock()
|
s.mux.Lock()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
|
@ -147,28 +147,27 @@ func dualStackDialContext(ctx context.Context, network, address string) (net.Con
|
||||||
go startRacer(ctx, network+"4", host, false)
|
go startRacer(ctx, network+"4", host, false)
|
||||||
go startRacer(ctx, network+"6", host, true)
|
go startRacer(ctx, network+"6", host, true)
|
||||||
|
|
||||||
for {
|
for res := range results {
|
||||||
select {
|
if res.error == nil {
|
||||||
case res := <-results:
|
return res.Conn, nil
|
||||||
if res.error == nil {
|
}
|
||||||
return res.Conn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !res.ipv6 {
|
if !res.ipv6 {
|
||||||
primary = res
|
primary = res
|
||||||
|
} else {
|
||||||
|
fallback = res
|
||||||
|
}
|
||||||
|
|
||||||
|
if primary.done && fallback.done {
|
||||||
|
if primary.resolved {
|
||||||
|
return nil, primary.error
|
||||||
|
} else if fallback.resolved {
|
||||||
|
return nil, fallback.error
|
||||||
} else {
|
} else {
|
||||||
fallback = res
|
return nil, primary.error
|
||||||
}
|
|
||||||
|
|
||||||
if primary.done && fallback.done {
|
|
||||||
if primary.resolved {
|
|
||||||
return nil, primary.error
|
|
||||||
} else if fallback.resolved {
|
|
||||||
return nil, fallback.error
|
|
||||||
} else {
|
|
||||||
return nil, primary.error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("never touched")
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (s *Snell) Read(b []byte) (int, error) {
|
||||||
if s.buffer[0] == CommandTunnel {
|
if s.buffer[0] == CommandTunnel {
|
||||||
return s.Conn.Read(b)
|
return s.Conn.Read(b)
|
||||||
} else if s.buffer[0] != CommandError {
|
} else if s.buffer[0] != CommandError {
|
||||||
return 0, errors.New("Command not support")
|
return 0, errors.New("command not support")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandError
|
// CommandError
|
||||||
|
|
|
@ -287,5 +287,4 @@ func packData(buffer *bytes.Buffer, suffix []byte) {
|
||||||
binary.BigEndian.PutUint16(d[3:5], uint16(len(suffix)&0xFFFF))
|
binary.BigEndian.PutUint16(d[3:5], uint16(len(suffix)&0xFFFF))
|
||||||
buffer.Write(d)
|
buffer.Write(d)
|
||||||
buffer.Write(suffix)
|
buffer.Write(suffix)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,6 @@ func (a *authChain) packData(outData []byte, data []byte, randLength int) {
|
||||||
binary.LittleEndian.PutUint32(key[userKeyLen:], a.chunkID)
|
binary.LittleEndian.PutUint32(key[userKeyLen:], a.chunkID)
|
||||||
a.lastClientHash = a.hmac(key, outData[:outLength])
|
a.lastClientHash = a.hmac(key, outData[:outLength])
|
||||||
copy(outData[outLength:], a.lastClientHash[:2])
|
copy(outData[outLength:], a.lastClientHash[:2])
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const authHeadLength = 4 + 8 + 4 + 16 + 4
|
const authHeadLength = 4 + 8 + 4 + 16 + 4
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (r *aeadReader) Read(b []byte) (int, error) {
|
||||||
|
|
||||||
size := int(binary.BigEndian.Uint16(r.sizeBuf))
|
size := int(binary.BigEndian.Uint16(r.sizeBuf))
|
||||||
if size > maxSize {
|
if size > maxSize {
|
||||||
return 0, errors.New("Buffer is larger than standard")
|
return 0, errors.New("buffer is larger than standard")
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.Get(size)
|
buf := pool.Get(size)
|
||||||
|
|
|
@ -47,7 +47,7 @@ func (cr *chunkReader) Read(b []byte) (int, error) {
|
||||||
|
|
||||||
size := int(binary.BigEndian.Uint16(cr.sizeBuf))
|
size := int(binary.BigEndian.Uint16(cr.sizeBuf))
|
||||||
if size > maxSize {
|
if size > maxSize {
|
||||||
return 0, errors.New("Buffer is larger than standard")
|
return 0, errors.New("buffer is larger than standard")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) >= size {
|
if len(b) >= size {
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package vmess
|
package vmess
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
)
|
)
|
||||||
|
@ -37,11 +35,6 @@ var CipherMapping = map[string]byte{
|
||||||
"chacha20-poly1305": SecurityCHACHA20POLY1305,
|
"chacha20-poly1305": SecurityCHACHA20POLY1305,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
clientSessionCache tls.ClientSessionCache
|
|
||||||
once sync.Once
|
|
||||||
)
|
|
||||||
|
|
||||||
// Command types
|
// Command types
|
||||||
const (
|
const (
|
||||||
CommandTCP byte = 1
|
CommandTCP byte = 1
|
||||||
|
@ -106,7 +99,7 @@ func NewClient(config Config) (*Client, error) {
|
||||||
security = SecurityAES128GCM
|
security = SecurityAES128GCM
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Unknown security type: %s", config.Security)
|
return nil, fmt.Errorf("unknown security type: %s", config.Security)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
|
|
|
@ -73,7 +73,7 @@ func (wsc *websocketConn) Close() error {
|
||||||
errors = append(errors, err.Error())
|
errors = append(errors, err.Error())
|
||||||
}
|
}
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return fmt.Errorf("Failed to close connection: %s", strings.Join(errors, ","))
|
return fmt.Errorf("failed to close connection: %s", strings.Join(errors, ","))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) {
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
reason = resp.Status
|
reason = resp.Status
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("Dial %s error: %s", uri.Host, reason)
|
return nil, fmt.Errorf("dial %s error: %s", uri.Host, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &websocketConn{
|
return &websocketConn{
|
||||||
|
|
|
@ -264,11 +264,11 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
||||||
for idx, mapping := range proxiesConfig {
|
for idx, mapping := range proxiesConfig {
|
||||||
proxy, err := outbound.ParseProxy(mapping)
|
proxy, err := outbound.ParseProxy(mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Proxy %d: %w", idx, err)
|
return nil, nil, fmt.Errorf("proxy %d: %w", idx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exist := proxies[proxy.Name()]; exist {
|
if _, exist := proxies[proxy.Name()]; exist {
|
||||||
return nil, nil, fmt.Errorf("Proxy %s is the duplicate name", proxy.Name())
|
return nil, nil, fmt.Errorf("proxy %s is the duplicate name", proxy.Name())
|
||||||
}
|
}
|
||||||
proxies[proxy.Name()] = proxy
|
proxies[proxy.Name()] = proxy
|
||||||
proxyList = append(proxyList, proxy.Name())
|
proxyList = append(proxyList, proxy.Name())
|
||||||
|
@ -278,7 +278,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
||||||
for idx, mapping := range groupsConfig {
|
for idx, mapping := range groupsConfig {
|
||||||
groupName, existName := mapping["name"].(string)
|
groupName, existName := mapping["name"].(string)
|
||||||
if !existName {
|
if !existName {
|
||||||
return nil, nil, fmt.Errorf("ProxyGroup %d: missing name", idx)
|
return nil, nil, fmt.Errorf("proxy group %d: missing name", idx)
|
||||||
}
|
}
|
||||||
proxyList = append(proxyList, groupName)
|
proxyList = append(proxyList, groupName)
|
||||||
}
|
}
|
||||||
|
@ -313,12 +313,12 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
||||||
for idx, mapping := range groupsConfig {
|
for idx, mapping := range groupsConfig {
|
||||||
group, err := outboundgroup.ParseProxyGroup(mapping, proxies, providersMap)
|
group, err := outboundgroup.ParseProxyGroup(mapping, proxies, providersMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("ProxyGroup[%d]: %w", idx, err)
|
return nil, nil, fmt.Errorf("proxy group[%d]: %w", idx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
groupName := group.Name()
|
groupName := group.Name()
|
||||||
if _, exist := proxies[groupName]; exist {
|
if _, exist := proxies[groupName]; exist {
|
||||||
return nil, nil, fmt.Errorf("ProxyGroup %s: the duplicate name", groupName)
|
return nil, nil, fmt.Errorf("proxy group %s: the duplicate name", groupName)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxies[groupName] = outbound.NewProxy(group)
|
proxies[groupName] = outbound.NewProxy(group)
|
||||||
|
@ -373,11 +373,11 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, error) {
|
||||||
target = rule[2]
|
target = rule[2]
|
||||||
params = rule[3:]
|
params = rule[3:]
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Rules[%d] [%s] error: format invalid", idx, line)
|
return nil, fmt.Errorf("rules[%d] [%s] error: format invalid", idx, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := proxies[target]; !ok {
|
if _, ok := proxies[target]; !ok {
|
||||||
return nil, fmt.Errorf("Rules[%d] [%s] error: proxy [%s] not found", idx, line, target)
|
return nil, fmt.Errorf("rules[%d] [%s] error: proxy [%s] not found", idx, line, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = trimArr(rule)
|
rule = trimArr(rule)
|
||||||
|
@ -389,7 +389,7 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, error) {
|
||||||
log.Warnln("Rules[%d] [%s] don't support current OS, skip", idx, line)
|
log.Warnln("Rules[%d] [%s] don't support current OS, skip", idx, line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("Rules[%d] [%s] error: %s", idx, line, parseErr.Error())
|
return nil, fmt.Errorf("rules[%d] [%s] error: %s", idx, line, parseErr.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
rules = append(rules, parsed)
|
rules = append(rules, parsed)
|
||||||
|
@ -499,7 +499,7 @@ func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
||||||
|
|
||||||
func parseDNS(cfg RawDNS, hosts *trie.DomainTrie) (*DNS, error) {
|
func parseDNS(cfg RawDNS, hosts *trie.DomainTrie) (*DNS, error) {
|
||||||
if cfg.Enable && len(cfg.NameServer) == 0 {
|
if cfg.Enable && len(cfg.NameServer) == 0 {
|
||||||
return nil, fmt.Errorf("If DNS configuration is turned on, NameServer cannot be empty")
|
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsCfg := &DNS{
|
dnsCfg := &DNS{
|
||||||
|
|
|
@ -32,18 +32,18 @@ func initMMDB() error {
|
||||||
if _, err := os.Stat(C.Path.MMDB()); os.IsNotExist(err) {
|
if _, err := os.Stat(C.Path.MMDB()); os.IsNotExist(err) {
|
||||||
log.Infoln("Can't find MMDB, start download")
|
log.Infoln("Can't find MMDB, start download")
|
||||||
if err := downloadMMDB(C.Path.MMDB()); err != nil {
|
if err := downloadMMDB(C.Path.MMDB()); err != nil {
|
||||||
return fmt.Errorf("Can't download MMDB: %s", err.Error())
|
return fmt.Errorf("can't download MMDB: %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mmdb.Verify() {
|
if !mmdb.Verify() {
|
||||||
log.Warnln("MMDB invalid, remove and download")
|
log.Warnln("MMDB invalid, remove and download")
|
||||||
if err := os.Remove(C.Path.MMDB()); err != nil {
|
if err := os.Remove(C.Path.MMDB()); err != nil {
|
||||||
return fmt.Errorf("Can't remove invalid MMDB: %s", err.Error())
|
return fmt.Errorf("can't remove invalid MMDB: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := downloadMMDB(C.Path.MMDB()); err != nil {
|
if err := downloadMMDB(C.Path.MMDB()); err != nil {
|
||||||
return fmt.Errorf("Can't download MMDB: %s", err.Error())
|
return fmt.Errorf("can't download MMDB: %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func Init(dir string) error {
|
||||||
// initial homedir
|
// initial homedir
|
||||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||||
return fmt.Errorf("Can't create config directory %s: %s", dir, err.Error())
|
return fmt.Errorf("can't create config directory %s: %s", dir, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func Init(dir string) error {
|
||||||
log.Infoln("Can't find config, create a initial config file")
|
log.Infoln("Can't find config, create a initial config file")
|
||||||
f, err := os.OpenFile(C.Path.Config(), os.O_CREATE|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(C.Path.Config(), os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Can't create file %s: %s", C.Path.Config(), err.Error())
|
return fmt.Errorf("can't create file %s: %s", C.Path.Config(), err.Error())
|
||||||
}
|
}
|
||||||
f.Write([]byte(`port: 7890`))
|
f.Write([]byte(`port: 7890`))
|
||||||
f.Close()
|
f.Close()
|
||||||
|
@ -72,7 +72,7 @@ func Init(dir string) error {
|
||||||
|
|
||||||
// initial mmdb
|
// initial mmdb
|
||||||
if err := initMMDB(); err != nil {
|
if err := initMMDB(); err != nil {
|
||||||
return fmt.Errorf("Can't initial MMDB: %w", err)
|
return fmt.Errorf("can't initial MMDB: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,6 @@ func trimArr(arr []string) (r []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func or(pointers ...*int) *int {
|
|
||||||
for _, p := range pointers {
|
|
||||||
if p != nil {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pointers[len(pointers)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
|
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
|
||||||
// Meanwhile, record the original index in the config file.
|
// Meanwhile, record the original index in the config file.
|
||||||
// If loop is detected, return an error with location of loop.
|
// If loop is detected, return an error with location of loop.
|
||||||
|
@ -153,5 +144,5 @@ func proxyGroupsDagSort(groupsConfig []map[string]interface{}) error {
|
||||||
loopElements = append(loopElements, name)
|
loopElements = append(loopElements, name)
|
||||||
delete(graph, name)
|
delete(graph, name)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Loop is detected in ProxyGroup, please check following ProxyGroups: %v", loopElements)
|
return fmt.Errorf("loop is detected in ProxyGroup, please check following ProxyGroups: %v", loopElements)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ func withHosts(hosts *trie.DomainTrie) middleware {
|
||||||
msg.RecursionAvailable = true
|
msg.RecursionAvailable = true
|
||||||
|
|
||||||
w.WriteMsg(msg)
|
w.WriteMsg(msg)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +98,6 @@ func withFakeIP(fakePool *fakeip.Pool) middleware {
|
||||||
msg.RecursionAvailable = true
|
msg.RecursionAvailable = true
|
||||||
|
|
||||||
w.WriteMsg(msg)
|
w.WriteMsg(msg)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +128,6 @@ func withResolver(resolver *Resolver) handler {
|
||||||
msg.SetRcode(r, msg.Rcode)
|
msg.SetRcode(r, msg.Rcode)
|
||||||
msg.Authoritative = true
|
msg.Authoritative = true
|
||||||
w.WriteMsg(msg)
|
w.WriteMsg(msg)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ func (r *Resolver) Exchange(m *D.Msg) (msg *D.Msg, err error) {
|
||||||
setMsgTTL(msg, uint32(1)) // Continue fetch
|
setMsgTTL(msg, uint32(1)) // Continue fetch
|
||||||
go r.exchangeWithoutCache(m)
|
go r.exchangeWithoutCache(m)
|
||||||
} else {
|
} else {
|
||||||
setMsgTTL(msg, uint32(expireTime.Sub(time.Now()).Seconds()))
|
setMsgTTL(msg, uint32(time.Until(expireTime).Seconds()))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func (r *Resolver) batchExchange(clients []dnsClient, m *D.Msg) (msg *D.Msg, err
|
||||||
|
|
||||||
elm := fast.Wait()
|
elm := fast.Wait()
|
||||||
if elm == nil {
|
if elm == nil {
|
||||||
err := errors.New("All DNS requests failed")
|
err := errors.New("all DNS requests failed")
|
||||||
if fErr := fast.Error(); fErr != nil {
|
if fErr := fast.Error(); fErr != nil {
|
||||||
err = fmt.Errorf("%w, first error: %s", err, fErr.Error())
|
err = fmt.Errorf("%w, first error: %s", err, fErr.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func readConfig(path string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, fmt.Errorf("Configuration file %s is empty", path)
|
return nil, fmt.Errorf("configuration file %s is empty", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, err
|
return data, err
|
||||||
|
@ -101,7 +101,7 @@ func GetGeneral() *config.General {
|
||||||
func updateExperimental(c *config.Config) {}
|
func updateExperimental(c *config.Config) {}
|
||||||
|
|
||||||
func updateDNS(c *config.DNS) {
|
func updateDNS(c *config.DNS) {
|
||||||
if c.Enable == false {
|
if !c.Enable {
|
||||||
resolver.DefaultResolver = nil
|
resolver.DefaultResolver = nil
|
||||||
tunnel.SetResolver(nil)
|
tunnel.SetResolver(nil)
|
||||||
dns.ReCreateServer("", nil)
|
dns.ReCreateServer("", nil)
|
||||||
|
|
|
@ -64,7 +64,6 @@ func Subscribe() observable.Subscription {
|
||||||
|
|
||||||
func UnSubscribe(sub observable.Subscription) {
|
func UnSubscribe(sub observable.Subscription) {
|
||||||
source.UnSubscribe(sub)
|
source.UnSubscribe(sub)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Level() LogLevel {
|
func Level() LogLevel {
|
||||||
|
|
5
main.go
5
main.go
|
@ -10,7 +10,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/config"
|
"github.com/Dreamacro/clash/config"
|
||||||
"github.com/Dreamacro/clash/constant"
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/hub"
|
"github.com/Dreamacro/clash/hub"
|
||||||
"github.com/Dreamacro/clash/hub/executor"
|
"github.com/Dreamacro/clash/hub/executor"
|
||||||
|
@ -76,10 +75,10 @@ func main() {
|
||||||
if testConfig {
|
if testConfig {
|
||||||
if _, err := executor.Parse(); err != nil {
|
if _, err := executor.Parse(); err != nil {
|
||||||
log.Errorln(err.Error())
|
log.Errorln(err.Error())
|
||||||
fmt.Printf("configuration file %s test failed\n", constant.Path.Config())
|
fmt.Printf("configuration file %s test failed\n", C.Path.Config())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Printf("configuration file %s test is successful\n", constant.Path.Config())
|
fmt.Printf("configuration file %s test is successful\n", C.Path.Config())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ func (l *HttpListener) Address() string {
|
||||||
func canActivate(loginStr string, authenticator auth.Authenticator, cache *cache.Cache) (ret bool) {
|
func canActivate(loginStr string, authenticator auth.Authenticator, cache *cache.Cache) (ret bool) {
|
||||||
if result := cache.Get(loginStr); result != nil {
|
if result := cache.Get(loginStr); result != nil {
|
||||||
ret = result.(bool)
|
ret = result.(bool)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
loginData, err := base64.StdEncoding.DecodeString(loginStr)
|
loginData, err := base64.StdEncoding.DecodeString(loginStr)
|
||||||
login := strings.Split(string(loginData), ":")
|
login := strings.Split(string(loginData), ":")
|
||||||
|
@ -80,7 +81,7 @@ func HandleConn(conn net.Conn, cache *cache.Cache) {
|
||||||
authenticator := authStore.Authenticator()
|
authenticator := authStore.Authenticator()
|
||||||
if authenticator != nil {
|
if authenticator != nil {
|
||||||
if authStrings := strings.Split(request.Header.Get("Proxy-Authorization"), " "); len(authStrings) != 2 {
|
if authStrings := strings.Split(request.Header.Get("Proxy-Authorization"), " "); len(authStrings) != 2 {
|
||||||
_, err = conn.Write([]byte("HTTP/1.1 407 Proxy Authentication Required\r\nProxy-Authenticate: Basic\r\n\r\n"))
|
conn.Write([]byte("HTTP/1.1 407 Proxy Authentication Required\r\nProxy-Authenticate: Basic\r\n\r\n"))
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return
|
return
|
||||||
} else if !canActivate(authStrings[1], authenticator, cache) {
|
} else if !canActivate(authStrings[1], authenticator, cache) {
|
||||||
|
|
|
@ -30,14 +30,8 @@ var (
|
||||||
httpMux sync.Mutex
|
httpMux sync.Mutex
|
||||||
redirMux sync.Mutex
|
redirMux sync.Mutex
|
||||||
mixedMux sync.Mutex
|
mixedMux sync.Mutex
|
||||||
tunMux sync.Mutex
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type listener interface {
|
|
||||||
Close()
|
|
||||||
Address() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Ports struct {
|
type Ports struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
SocksPort int `json:"socks-port"`
|
SocksPort int `json:"socks-port"`
|
||||||
|
|
|
@ -34,5 +34,4 @@ func (c *packet) LocalAddr() net.Addr {
|
||||||
|
|
||||||
func (c *packet) Drop() {
|
func (c *packet) Drop() {
|
||||||
pool.Put(c.buf)
|
pool.Put(c.buf)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,4 @@ func (c *packet) LocalAddr() net.Addr {
|
||||||
|
|
||||||
func (c *packet) Drop() {
|
func (c *packet) Drop() {
|
||||||
pool.Put(c.bufRef)
|
pool.Put(c.bufRef)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errPayload = errors.New("payload error")
|
errPayload = errors.New("payload error")
|
||||||
errParams = errors.New("params error")
|
|
||||||
ErrPlatformNotSupport = errors.New("not support on this platform")
|
ErrPlatformNotSupport = errors.New("not support on this platform")
|
||||||
ErrInvalidNetwork = errors.New("invalid network")
|
ErrInvalidNetwork = errors.New("invalid network")
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr n
|
||||||
from = fAddr
|
from = fAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err = packet.WriteBack(buf[:n], from)
|
_, err = packet.WriteBack(buf[:n], from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue