fix: go1.19 compile

This commit is contained in:
wwqgtxx 2023-06-06 10:47:50 +08:00
parent dafecebdc0
commit ad11a2b813
5 changed files with 59 additions and 6 deletions

View 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))
}

View file

@ -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
} }

View file

@ -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
View file

@ -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

View file

@ -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
} }