mirror of
https://github.com/amnezia-vpn/amneziawg-go.git
synced 2025-08-11 05:52:51 +02:00
144 lines
3.6 KiB
Go
144 lines
3.6 KiB
Go
package awg
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"slices"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/tevino/abool"
|
|
)
|
|
|
|
type aSecCfgType struct {
|
|
IsSet bool
|
|
JunkPacketCount int
|
|
JunkPacketMinSize int
|
|
JunkPacketMaxSize int
|
|
InitHeaderJunkSize int
|
|
ResponseHeaderJunkSize int
|
|
CookieReplyHeaderJunkSize int
|
|
TransportHeaderJunkSize int
|
|
InitPacketMagicHeader uint32
|
|
ResponsePacketMagicHeader uint32
|
|
UnderloadPacketMagicHeader uint32
|
|
TransportPacketMagicHeader uint32
|
|
// InitPacketMagicHeader Limit
|
|
// ResponsePacketMagicHeader Limit
|
|
// UnderloadPacketMagicHeader Limit
|
|
// TransportPacketMagicHeader Limit
|
|
}
|
|
|
|
type Limit struct {
|
|
Min uint32
|
|
Max uint32
|
|
HeaderType uint32
|
|
}
|
|
|
|
func NewLimit(min, max, headerType uint32) (Limit, error) {
|
|
if min > max {
|
|
return Limit{}, fmt.Errorf("min (%d) cannot be greater than max (%d)", min, max)
|
|
}
|
|
|
|
return Limit{
|
|
Min: min,
|
|
Max: max,
|
|
HeaderType: headerType,
|
|
}, nil
|
|
}
|
|
|
|
func ParseMagicHeader(key, value string, defaultHeaderType uint32) (Limit, error) {
|
|
// tempAwg.ASecCfg.InitPacketMagicHeader, err = awg.NewLimit(uint32(initPacketMagicHeaderMin), uint32(initPacketMagicHeaderMax), DNewLimit(min, max, headerType)efaultMessageInitiationType)
|
|
// var min, max, headerType uint32
|
|
// _, err := fmt.Sscanf(value, "%d-%d:%d", &min, &max, &headerType)
|
|
// if err != nil {
|
|
// return Limit{}, fmt.Errorf("invalid magic header format: %s", value)
|
|
// }
|
|
|
|
limits := strings.Split(value, "-")
|
|
if len(limits) != 2 {
|
|
return Limit{}, fmt.Errorf("invalid format for key: %s; %s", key, value)
|
|
}
|
|
|
|
min, err := strconv.ParseUint(limits[0], 10, 32)
|
|
if err != nil {
|
|
return Limit{}, fmt.Errorf("parse min key: %s; value: ; %w", key, limits[0], err)
|
|
}
|
|
|
|
max, err := strconv.ParseUint(limits[1], 10, 32)
|
|
if err != nil {
|
|
return Limit{}, fmt.Errorf("parse max key: %s; value: ; %w", key, limits[0], err)
|
|
}
|
|
|
|
limit, err := NewLimit(uint32(min), uint32(max), defaultHeaderType)
|
|
if err != nil {
|
|
return Limit{}, fmt.Errorf("new lmit key: %s; value: ; %w", key, limits[0], err)
|
|
}
|
|
|
|
return limit, nil
|
|
}
|
|
|
|
type Limits []Limit
|
|
|
|
func NewLimits(limits []Limit) Limits {
|
|
slices.SortFunc(limits, func(a, b Limit) int {
|
|
if a.Min < b.Min {
|
|
return -1
|
|
} else if a.Min > b.Min {
|
|
return 1
|
|
}
|
|
return 0
|
|
})
|
|
|
|
return Limits(limits)
|
|
}
|
|
|
|
type Protocol struct {
|
|
IsASecOn abool.AtomicBool
|
|
// TODO: revision the need of the mutex
|
|
ASecMux sync.RWMutex
|
|
ASecCfg aSecCfgType
|
|
JunkCreator junkCreator
|
|
|
|
HandshakeHandler SpecialHandshakeHandler
|
|
}
|
|
|
|
func (protocol *Protocol) CreateInitHeaderJunk() ([]byte, error) {
|
|
return protocol.createHeaderJunk(protocol.ASecCfg.InitHeaderJunkSize)
|
|
}
|
|
|
|
func (protocol *Protocol) CreateResponseHeaderJunk() ([]byte, error) {
|
|
return protocol.createHeaderJunk(protocol.ASecCfg.ResponseHeaderJunkSize)
|
|
}
|
|
|
|
func (protocol *Protocol) CreateCookieReplyHeaderJunk() ([]byte, error) {
|
|
return protocol.createHeaderJunk(protocol.ASecCfg.CookieReplyHeaderJunkSize)
|
|
}
|
|
|
|
func (protocol *Protocol) CreateTransportHeaderJunk(packetSize int) ([]byte, error) {
|
|
return protocol.createHeaderJunk(protocol.ASecCfg.TransportHeaderJunkSize, packetSize)
|
|
}
|
|
|
|
func (protocol *Protocol) createHeaderJunk(junkSize int, optExtraSize ...int) ([]byte, error) {
|
|
extraSize := 0
|
|
if len(optExtraSize) == 1 {
|
|
extraSize = optExtraSize[0]
|
|
}
|
|
|
|
var junk []byte
|
|
protocol.ASecMux.RLock()
|
|
if junkSize != 0 {
|
|
buf := make([]byte, 0, junkSize+extraSize)
|
|
writer := bytes.NewBuffer(buf[:0])
|
|
err := protocol.JunkCreator.AppendJunk(writer, junkSize)
|
|
if err != nil {
|
|
protocol.ASecMux.RUnlock()
|
|
return nil, err
|
|
}
|
|
junk = writer.Bytes()
|
|
}
|
|
protocol.ASecMux.RUnlock()
|
|
|
|
return junk, nil
|
|
}
|