114 lines
2.7 KiB
Go
114 lines
2.7 KiB
Go
package tunnel
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/xtaci/kcp-go/v5"
|
|
"github.com/xtaci/smux"
|
|
"golang.org/x/crypto/pbkdf2"
|
|
)
|
|
|
|
type ClientConfig struct {
|
|
ServerAddress string
|
|
BlockCrypt kcp.BlockCrypt
|
|
DataShards int
|
|
ParityShards int
|
|
Credentials interface{}
|
|
ConfigureConn ConfigureConnFunc
|
|
AuthenticationTimeout time.Duration
|
|
ProxyRequestTimeout time.Duration
|
|
SmuxConfig *smux.Config
|
|
}
|
|
|
|
// nolint: go-mnd
|
|
func DefaultClientConfig() *ClientConfig {
|
|
unencryptedBlock, err := kcp.NewNoneBlockCrypt(nil)
|
|
if err != nil { // should never happen
|
|
panic(errors.WithStack(err))
|
|
}
|
|
|
|
smuxConfig := smux.DefaultConfig()
|
|
smuxConfig.Version = 2
|
|
smuxConfig.KeepAliveInterval = 10 * time.Second
|
|
smuxConfig.MaxReceiveBuffer = 4194304
|
|
smuxConfig.MaxStreamBuffer = 2097152
|
|
|
|
return &ClientConfig{
|
|
ServerAddress: "127.0.0.1:36543",
|
|
BlockCrypt: unencryptedBlock,
|
|
DataShards: 3,
|
|
ParityShards: 10,
|
|
Credentials: nil,
|
|
ConfigureConn: DefaultClientConfigureConn,
|
|
AuthenticationTimeout: 30 * time.Second,
|
|
ProxyRequestTimeout: 5 * time.Second,
|
|
SmuxConfig: smuxConfig,
|
|
}
|
|
}
|
|
|
|
type ClientConfigFunc func(c *ClientConfig)
|
|
|
|
func WithClientServerAddress(addr string) ClientConfigFunc {
|
|
return func(conf *ClientConfig) {
|
|
conf.ServerAddress = addr
|
|
}
|
|
}
|
|
|
|
func WithClientCredentials(credentials interface{}) ClientConfigFunc {
|
|
return func(conf *ClientConfig) {
|
|
conf.Credentials = credentials
|
|
}
|
|
}
|
|
|
|
func WithClientBlockCrypt(alg string, pass, salt string, iterations, keyLen int) ClientConfigFunc {
|
|
return func(conf *ClientConfig) {
|
|
key := pbkdf2.Key([]byte(pass), []byte(salt), iterations, keyLen, sha1.New)
|
|
|
|
block, err := createBlockCrypt(alg, key)
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "could not create block crypt"))
|
|
}
|
|
|
|
conf.BlockCrypt = block
|
|
}
|
|
}
|
|
|
|
func WithClientConfigureConn(fn ConfigureConnFunc) ClientConfigFunc {
|
|
return func(conf *ClientConfig) {
|
|
conf.ConfigureConn = fn
|
|
}
|
|
}
|
|
|
|
func WithClientSmuxConfig(c *smux.Config) ClientConfigFunc {
|
|
return func(conf *ClientConfig) {
|
|
conf.SmuxConfig = c
|
|
}
|
|
}
|
|
|
|
// nolint: go-mnd
|
|
func DefaultClientConfigureConn(conn *kcp.UDPSession) error {
|
|
// Based on kcptun default configuration, mode 'fast3'
|
|
conn.SetStreamMode(true)
|
|
conn.SetWriteDelay(false)
|
|
conn.SetNoDelay(1, 10, 2, 1)
|
|
conn.SetWindowSize(128, 512)
|
|
conn.SetMtu(1400)
|
|
conn.SetACKNoDelay(true)
|
|
|
|
if err := conn.SetReadBuffer(16777217); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
if err := conn.SetWriteBuffer(16777217); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
if err := conn.SetDSCP(46); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
return nil
|
|
}
|