fix: go1.19 compile
This commit is contained in:
parent
a0c7641ad5
commit
e0faffbfbd
5 changed files with 59 additions and 6 deletions
49
common/utils/string_unsafe.go
Normal file
49
common/utils/string_unsafe.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// sliceHeader is equivalent to reflect.SliceHeader, but represents the pointer
|
||||||
|
// to the underlying array as unsafe.Pointer rather than uintptr, allowing
|
||||||
|
// sliceHeaders to be directly converted to slice objects.
|
||||||
|
type sliceHeader struct {
|
||||||
|
Data unsafe.Pointer
|
||||||
|
Len int
|
||||||
|
Cap int
|
||||||
|
}
|
||||||
|
|
||||||
|
// slice returns a slice whose underlying array starts at ptr an which length
|
||||||
|
// and capacity are len.
|
||||||
|
func slice[T any](ptr *T, length int) []T {
|
||||||
|
var s []T
|
||||||
|
hdr := (*sliceHeader)(unsafe.Pointer(&s))
|
||||||
|
hdr.Data = unsafe.Pointer(ptr)
|
||||||
|
hdr.Len = length
|
||||||
|
hdr.Cap = length
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringHeader is equivalent to reflect.StringHeader, but represents the
|
||||||
|
// pointer to the underlying array as unsafe.Pointer rather than uintptr,
|
||||||
|
// allowing StringHeaders to be directly converted to strings.
|
||||||
|
type stringHeader struct {
|
||||||
|
Data unsafe.Pointer
|
||||||
|
Len int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImmutableBytesFromString is equivalent to []byte(s), except that it uses the
|
||||||
|
// same memory backing s instead of making a heap-allocated copy. This is only
|
||||||
|
// valid if the returned slice is never mutated.
|
||||||
|
func ImmutableBytesFromString(s string) []byte {
|
||||||
|
shdr := (*stringHeader)(unsafe.Pointer(&s))
|
||||||
|
return slice((*byte)(shdr.Data), shdr.Len)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFromImmutableBytes is equivalent to string(bs), except that it uses
|
||||||
|
// the same memory backing bs instead of making a heap-allocated copy. This is
|
||||||
|
// only valid if bs is never mutated after StringFromImmutableBytes returns.
|
||||||
|
func StringFromImmutableBytes(bs []byte) string {
|
||||||
|
// This is cheaper than messing with StringHeader and SliceHeader, which as
|
||||||
|
// of this writing produces many dead stores of zeroes. Compare
|
||||||
|
// strings.Builder.String().
|
||||||
|
return *(*string)(unsafe.Pointer(&bs))
|
||||||
|
}
|
|
@ -24,6 +24,8 @@ var (
|
||||||
|
|
||||||
var interfaces = singledo.NewSingle[map[string]*Interface](time.Second * 20)
|
var interfaces = singledo.NewSingle[map[string]*Interface](time.Second * 20)
|
||||||
|
|
||||||
|
const FlagRunning = 32 // interface is in running state, compatibility with golang<1.20
|
||||||
|
|
||||||
func ResolveInterface(name string) (*Interface, error) {
|
func ResolveInterface(name string) (*Interface, error) {
|
||||||
value, err, _ := interfaces.Do(func() (map[string]*Interface, error) {
|
value, err, _ := interfaces.Do(func() (map[string]*Interface, error) {
|
||||||
ifaces, err := net.Interfaces()
|
ifaces, err := net.Interfaces()
|
||||||
|
@ -39,7 +41,7 @@ func ResolveInterface(name string) (*Interface, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// if not available device like Meta, dummy0, docker0, etc.
|
// if not available device like Meta, dummy0, docker0, etc.
|
||||||
if (iface.Flags&net.FlagMulticast == 0) || (iface.Flags&net.FlagPointToPoint != 0) || (iface.Flags&net.FlagRunning == 0) {
|
if (iface.Flags&net.FlagMulticast == 0) || (iface.Flags&net.FlagPointToPoint != 0) || (iface.Flags&FlagRunning == 0) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ type DomainSet struct {
|
||||||
ranks, selects []int32
|
ranks, selects []int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type qElt struct{ s, e, col int }
|
||||||
|
|
||||||
// NewDomainSet creates a new *DomainSet struct, from a DomainTrie.
|
// NewDomainSet creates a new *DomainSet struct, from a DomainTrie.
|
||||||
func (t *DomainTrie[T]) NewDomainSet() *DomainSet {
|
func (t *DomainTrie[T]) NewDomainSet() *DomainSet {
|
||||||
reserveDomains := make([]string, 0)
|
reserveDomains := make([]string, 0)
|
||||||
|
@ -39,7 +41,6 @@ func (t *DomainTrie[T]) NewDomainSet() *DomainSet {
|
||||||
ss := &DomainSet{}
|
ss := &DomainSet{}
|
||||||
lIdx := 0
|
lIdx := 0
|
||||||
|
|
||||||
type qElt struct{ s, e, col int }
|
|
||||||
queue := []qElt{{0, len(keys), 0}}
|
queue := []qElt{{0, len(keys), 0}}
|
||||||
for i := 0; i < len(queue); i++ {
|
for i := 0; i < len(queue); i++ {
|
||||||
elt := queue[i]
|
elt := queue[i]
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/Dreamacro/clash
|
module github.com/Dreamacro/clash
|
||||||
|
|
||||||
go 1.20
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/3andne/restls-client-go v0.1.4
|
github.com/3andne/restls-client-go v0.1.4
|
||||||
|
|
|
@ -9,13 +9,14 @@ import (
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/adapter/inbound"
|
"github.com/Dreamacro/clash/adapter/inbound"
|
||||||
CN "github.com/Dreamacro/clash/common/net"
|
CN "github.com/Dreamacro/clash/common/net"
|
||||||
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
"github.com/Dreamacro/clash/tunnel/statistic"
|
"github.com/Dreamacro/clash/tunnel/statistic"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
|
@ -152,8 +153,8 @@ func Start(addr string, tlsAddr string, secret string,
|
||||||
}
|
}
|
||||||
|
|
||||||
func safeEuqal(a, b string) bool {
|
func safeEuqal(a, b string) bool {
|
||||||
aBuf := unsafe.Slice(unsafe.StringData(a), len(a))
|
aBuf := utils.ImmutableBytesFromString(a)
|
||||||
bBuf := unsafe.Slice(unsafe.StringData(b), len(b))
|
bBuf := utils.ImmutableBytesFromString(b)
|
||||||
return subtle.ConstantTimeCompare(aBuf, bBuf) == 1
|
return subtle.ConstantTimeCompare(aBuf, bBuf) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue