mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
153 lines
3.8 KiB
Go
153 lines
3.8 KiB
Go
package kcptun
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
|
|
"github.com/metacubex/mihomo/log"
|
|
|
|
"github.com/metacubex/kcp-go"
|
|
"golang.org/x/crypto/pbkdf2"
|
|
)
|
|
|
|
const (
|
|
// SALT is use for pbkdf2 key expansion
|
|
SALT = "kcp-go"
|
|
// maximum supported smux version
|
|
maxSmuxVer = 2
|
|
// scavenger check period
|
|
scavengePeriod = 5
|
|
)
|
|
|
|
type Config struct {
|
|
Key string `json:"key"`
|
|
Crypt string `json:"crypt"`
|
|
Mode string `json:"mode"`
|
|
Conn int `json:"conn"`
|
|
AutoExpire int `json:"autoexpire"`
|
|
ScavengeTTL int `json:"scavengettl"`
|
|
MTU int `json:"mtu"`
|
|
SndWnd int `json:"sndwnd"`
|
|
RcvWnd int `json:"rcvwnd"`
|
|
DataShard int `json:"datashard"`
|
|
ParityShard int `json:"parityshard"`
|
|
DSCP int `json:"dscp"`
|
|
NoComp bool `json:"nocomp"`
|
|
AckNodelay bool `json:"acknodelay"`
|
|
NoDelay int `json:"nodelay"`
|
|
Interval int `json:"interval"`
|
|
Resend int `json:"resend"`
|
|
NoCongestion int `json:"nc"`
|
|
SockBuf int `json:"sockbuf"`
|
|
SmuxVer int `json:"smuxver"`
|
|
SmuxBuf int `json:"smuxbuf"`
|
|
StreamBuf int `json:"streambuf"`
|
|
KeepAlive int `json:"keepalive"`
|
|
}
|
|
|
|
func (config *Config) FillDefaults() {
|
|
if config.Key == "" {
|
|
config.Key = "it's a secrect"
|
|
}
|
|
if config.Crypt == "" {
|
|
config.Crypt = "aes"
|
|
}
|
|
if config.Mode == "" {
|
|
config.Mode = "fast"
|
|
}
|
|
if config.Conn == 0 {
|
|
config.Conn = 1
|
|
}
|
|
if config.ScavengeTTL == 0 {
|
|
config.ScavengeTTL = 600
|
|
}
|
|
if config.MTU == 0 {
|
|
config.MTU = 1350
|
|
}
|
|
if config.SndWnd == 0 {
|
|
config.SndWnd = 128
|
|
}
|
|
if config.RcvWnd == 0 {
|
|
config.RcvWnd = 512
|
|
}
|
|
if config.DataShard == 0 {
|
|
config.DataShard = 10
|
|
}
|
|
if config.ParityShard == 0 {
|
|
config.ParityShard = 3
|
|
}
|
|
if config.Interval == 0 {
|
|
config.Interval = 50
|
|
}
|
|
if config.SockBuf == 0 {
|
|
config.SockBuf = 4194304
|
|
}
|
|
if config.SmuxVer == 0 {
|
|
config.SmuxVer = 1
|
|
}
|
|
if config.SmuxBuf == 0 {
|
|
config.SmuxBuf = 4194304
|
|
}
|
|
if config.StreamBuf == 0 {
|
|
config.StreamBuf = 2097152
|
|
}
|
|
if config.KeepAlive == 0 {
|
|
config.KeepAlive = 10
|
|
}
|
|
switch config.Mode {
|
|
case "normal":
|
|
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 40, 2, 1
|
|
case "fast":
|
|
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 30, 2, 1
|
|
case "fast2":
|
|
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
|
|
case "fast3":
|
|
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 10, 2, 1
|
|
}
|
|
|
|
// SMUX Version check
|
|
if config.SmuxVer > maxSmuxVer {
|
|
log.Warnln("unsupported smux version: %d", config.SmuxVer)
|
|
config.SmuxVer = maxSmuxVer
|
|
}
|
|
|
|
// Scavenge parameters check
|
|
if config.AutoExpire != 0 && config.ScavengeTTL > config.AutoExpire {
|
|
log.Warnln("WARNING: scavengettl is bigger than autoexpire, connections may race hard to use bandwidth.")
|
|
log.Warnln("Try limiting scavengettl to a smaller value.")
|
|
}
|
|
}
|
|
|
|
func (config *Config) NewBlock() (block kcp.BlockCrypt) {
|
|
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
|
|
switch config.Crypt {
|
|
case "null":
|
|
block = nil
|
|
case "tea":
|
|
block, _ = kcp.NewTEABlockCrypt(pass[:16])
|
|
case "xor":
|
|
block, _ = kcp.NewSimpleXORBlockCrypt(pass)
|
|
case "none":
|
|
block, _ = kcp.NewNoneBlockCrypt(pass)
|
|
case "aes-128":
|
|
block, _ = kcp.NewAESBlockCrypt(pass[:16])
|
|
case "aes-192":
|
|
block, _ = kcp.NewAESBlockCrypt(pass[:24])
|
|
case "blowfish":
|
|
block, _ = kcp.NewBlowfishBlockCrypt(pass)
|
|
case "twofish":
|
|
block, _ = kcp.NewTwofishBlockCrypt(pass)
|
|
case "cast5":
|
|
block, _ = kcp.NewCast5BlockCrypt(pass[:16])
|
|
case "3des":
|
|
block, _ = kcp.NewTripleDESBlockCrypt(pass[:24])
|
|
case "xtea":
|
|
block, _ = kcp.NewXTEABlockCrypt(pass[:16])
|
|
case "salsa20":
|
|
block, _ = kcp.NewSalsa20BlockCrypt(pass)
|
|
default:
|
|
config.Crypt = "aes"
|
|
block, _ = kcp.NewAESBlockCrypt(pass)
|
|
}
|
|
return
|
|
}
|