Migrate the AmneziaWG graft from the old sagernet base (506b763) onto v0.0.3, the base sing-box 1.14 uses. Strategy: start from v0.0.3, copy the net-new obfuscation files verbatim from the proven graft (27290b6), take the 6 modified device/ files wholesale from the graft, keep all tun/* and conn/* from v0.0.3. Net-new (copied from27290b6): device/magic-header.go + device/obf*.go (9). Modified (from27290b6): device/{send,receive,uapi,device,noise-protocol,cookie}.go. - receive.go: reverted two Go-1.22 'range int' loops to the v0.0.3 form (go 1.20). - cookie.go: keeps the 4-arg CreateReply(msgType) the grafted send.go calls. - noise-protocol.go: MessageEncapsulatingTransportSize=0 (AWG composes without the sagernet Bind.Send headroom prepend). §010 android UDP_GRO guard (fb8d8d8) intentionally DROPPED: v0.0.3 fixes the receive split-brain at source — bind_std.go now gates all 5 RX/offload paths on linux||android, and gso_linux.go splits coalesced packets on android. Re-inserting the guard would disable a now-working android RX-offload path. Requires on-device re-verification before release. go.mod: go 1.20, golang.org/x/sys v0.21.0 (v0.0.3 baseline). No amnezia-vpn import paths remain. Builds clean for linux/android/windows/darwin (library packages).
63 lines
1.2 KiB
Go
63 lines
1.2 KiB
Go
package device
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type magicHeader struct {
|
|
start uint32
|
|
end uint32
|
|
}
|
|
|
|
func newMagicHeader(spec string) (*magicHeader, error) {
|
|
parts := strings.Split(spec, "-")
|
|
if len(parts) < 1 || len(parts) > 2 {
|
|
return nil, errors.New("bad format")
|
|
}
|
|
|
|
start, err := strconv.ParseUint(parts[0], 10, 32)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse %s: %w", parts[0], err)
|
|
}
|
|
|
|
var end uint64
|
|
if len(parts) > 1 {
|
|
end, err = strconv.ParseUint(parts[1], 10, 32)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse %s: %w", parts[1], err)
|
|
}
|
|
} else {
|
|
end = start
|
|
}
|
|
|
|
if end < start {
|
|
return nil, errors.New("wrong range specified")
|
|
}
|
|
|
|
return &magicHeader{
|
|
start: uint32(start),
|
|
end: uint32(end),
|
|
}, nil
|
|
}
|
|
|
|
func (h *magicHeader) GenSpec() string {
|
|
if h.start == h.end {
|
|
return fmt.Sprintf("%d", h.start)
|
|
}
|
|
return fmt.Sprintf("%d-%d", h.start, h.end)
|
|
}
|
|
|
|
func (h *magicHeader) Validate(val uint32) bool {
|
|
return h.start <= val && val <= h.end
|
|
}
|
|
|
|
func (h *magicHeader) Generate() uint32 {
|
|
high := int64(h.end - h.start + 1)
|
|
r, _ := rand.Int(rand.Reader, big.NewInt(high))
|
|
return h.start + uint32(r.Int64())
|
|
}
|