From 4a6eaeb80263e836da9a13fc7b43cc78123dd1bb Mon Sep 17 00:00:00 2001 From: Daniel Ding Date: Sat, 1 Oct 2022 08:21:53 +0800 Subject: [PATCH] fea: socket: support to negotiate key --- .gitignore | 3 + VERSION | 2 +- cmd/api/v5/user.go | 2 +- core/version.h | 4 +- misc/learn/array.go | 1 + pkg/access/http/http.go | 2 +- pkg/access/pointer.go | 2 +- pkg/access/worker.go | 15 +++-- pkg/config/cert.go | 29 -------- pkg/config/common.go | 2 +- pkg/config/config.go | 2 +- pkg/config/point.go | 11 ++-- pkg/config/switch.go | 14 ++-- pkg/database/utils.go | 2 +- pkg/libol/kcpsocket.go | 22 ++++--- pkg/libol/message.go | 86 +++++++++++++++++++++++- pkg/libol/socket.go | 142 ++++++++++++++++++++++++++++++++++------ pkg/libol/tcpsocket.go | 21 +++--- pkg/libol/udpsocket.go | 21 +++--- pkg/libol/utils.go | 19 ++++-- pkg/libol/websocket.go | 21 +++--- pkg/switch/http.go | 2 +- pkg/switch/openlan.go | 2 +- pkg/switch/switch.go | 16 +++-- 24 files changed, 315 insertions(+), 128 deletions(-) diff --git a/.gitignore b/.gitignore index ed0590f..6e32125 100755 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ *.so *.dylib *.patch +*.rej +*.orig *.exe *.x86_64 *.rpm @@ -23,6 +25,7 @@ coverage.html /core/build/ /core/cmake-build-debug/ +# Temporary files confd-idl.h confd-idl.c confd-idl.ovsidl diff --git a/VERSION b/VERSION index 91a1d6c..2eb84e9 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.10.7 +22.09.10 diff --git a/cmd/api/v5/user.go b/cmd/api/v5/user.go index a1c59b7..7aa7bf1 100755 --- a/cmd/api/v5/user.go +++ b/cmd/api/v5/user.go @@ -139,7 +139,7 @@ func (u User) Commands(app *api.App) { Usage: "Add a new user", Flags: []cli.Flag{ &cli.StringFlag{Name: "name"}, - &cli.StringFlag{Name: "password", Value: libol.GenRandom(24)}, + &cli.StringFlag{Name: "password", Value: libol.GenString(24)}, &cli.StringFlag{Name: "role", Value: "guest"}, &cli.StringFlag{Name: "lease", Value: lease.Format(libol.LeaseTime)}, }, diff --git a/core/version.h b/core/version.h index 961300d..06bfa8c 100644 --- a/core/version.h +++ b/core/version.h @@ -10,8 +10,8 @@ #ifndef OPENUDP_VERSION_H #define OPENUDP_VERSION_H 1 -#define CORE_PACKAGE_STRING "opencore 5.10.7" -#define CORE_PACKAGE_VERSION "5.10.7" +#define CORE_PACKAGE_STRING "opencore 22.09.10" +#define CORE_PACKAGE_VERSION "22.09.10" #define CORE_LIB_VERSION 0 #define CORE_LIB_REVISION 0 diff --git a/misc/learn/array.go b/misc/learn/array.go index 918d15d..8ab8e5e 100755 --- a/misc/learn/array.go +++ b/misc/learn/array.go @@ -9,6 +9,7 @@ func InArray(data []int) { data[0] = 0x04 fmt.Println(data) } + func main() { var a = []int{1, 2, 3} diff --git a/pkg/access/http/http.go b/pkg/access/http/http.go index 0658be7..6c463b3 100755 --- a/pkg/access/http/http.go +++ b/pkg/access/http/http.go @@ -39,7 +39,7 @@ func (h *Http) Initialize() { Handler: r, } } - h.token = libol.GenRandom(32) + h.token = libol.GenString(32) libol.Info("Http.Initialize: AdminToken: %s", h.token) h.LoadRouter() } diff --git a/pkg/access/pointer.go b/pkg/access/pointer.go index a098e36..c29d524 100755 --- a/pkg/access/pointer.go +++ b/pkg/access/pointer.go @@ -71,7 +71,7 @@ func (p *MixPoint) Stop() { func (p *MixPoint) UUID() string { if p.uuid == "" { - p.uuid = libol.GenRandom(13) + p.uuid = libol.GenString(13) } return p.uuid } diff --git a/pkg/access/worker.go b/pkg/access/worker.go index eed1de2..44ddef2 100755 --- a/pkg/access/worker.go +++ b/pkg/access/worker.go @@ -80,23 +80,25 @@ type PrefixRule struct { } func GetSocketClient(p *config.Point) libol.SocketClient { + crypt := p.Crypt + block := libol.NewBlockCrypt(crypt.Algo, crypt.Secret) switch p.Protocol { case "kcp": c := libol.NewKcpConfig() - c.Block = config.GetBlock(p.Crypt) + c.Block = block c.RdQus = p.Queue.SockRd c.WrQus = p.Queue.SockWr return libol.NewKcpClient(p.Connection, c) case "tcp": c := &libol.TcpConfig{ - Block: config.GetBlock(p.Crypt), + Block: block, RdQus: p.Queue.SockRd, WrQus: p.Queue.SockWr, } return libol.NewTcpClient(p.Connection, c) case "udp": c := &libol.UdpConfig{ - Block: config.GetBlock(p.Crypt), + Block: block, Timeout: time.Duration(p.Timeout) * time.Second, RdQus: p.Queue.SockRd, WrQus: p.Queue.SockWr, @@ -104,14 +106,13 @@ func GetSocketClient(p *config.Point) libol.SocketClient { return libol.NewUdpClient(p.Connection, c) case "ws": c := &libol.WebConfig{ - Block: config.GetBlock(p.Crypt), RdQus: p.Queue.SockRd, WrQus: p.Queue.SockWr, } return libol.NewWebClient(p.Connection, c) case "wss": c := &libol.WebConfig{ - Block: config.GetBlock(p.Crypt), + Block: block, RdQus: p.Queue.SockRd, WrQus: p.Queue.SockWr, } @@ -124,7 +125,7 @@ func GetSocketClient(p *config.Point) libol.SocketClient { return libol.NewWebClient(p.Connection, c) default: c := &libol.TcpConfig{ - Block: config.GetBlock(p.Crypt), + Block: block, RdQus: p.Queue.SockRd, WrQus: p.Queue.SockWr, } @@ -387,7 +388,7 @@ func (w *Worker) OnSuccess(s *SocketWorker) error { func (w *Worker) UUID() string { if w.uuid == "" { - w.uuid = libol.GenRandom(13) + w.uuid = libol.GenString(13) } return w.uuid } diff --git a/pkg/config/cert.go b/pkg/config/cert.go index d152eed..df9892e 100755 --- a/pkg/config/cert.go +++ b/pkg/config/cert.go @@ -5,7 +5,6 @@ import ( "crypto/x509" "fmt" "github.com/luscis/openlan/pkg/libol" - "github.com/xtaci/kcp-go/v5" "io/ioutil" ) @@ -79,31 +78,3 @@ func (c *Cert) GetCertPool() *x509.CertPool { } return pool } - -func GetBlock(cfg *Crypt) kcp.BlockCrypt { - if cfg == nil || cfg.IsZero() { - return nil - } - var block kcp.BlockCrypt - pass := make([]byte, 64) - if len(cfg.Secret) <= 64 { - copy(pass, cfg.Secret) - } else { - copy(pass, []byte(cfg.Secret)[:64]) - } - switch cfg.Algo { - case "aes-128": - block, _ = kcp.NewAESBlockCrypt(pass[:16]) - case "aes-192": - block, _ = kcp.NewAESBlockCrypt(pass[:24]) - case "aes-256": - block, _ = kcp.NewAESBlockCrypt(pass[:32]) - case "tea": - block, _ = kcp.NewTEABlockCrypt(pass[:16]) - case "xtea": - block, _ = kcp.NewXTEABlockCrypt(pass[:16]) - default: - block, _ = kcp.NewSimpleXORBlockCrypt(pass) - } - return block -} diff --git a/pkg/config/common.go b/pkg/config/common.go index e815a07..421b510 100755 --- a/pkg/config/common.go +++ b/pkg/config/common.go @@ -47,5 +47,5 @@ func GetAlias() string { if hostname, err := os.Hostname(); err == nil { return strings.ToLower(hostname) } - return libol.GenRandom(13) + return libol.GenString(13) } diff --git a/pkg/config/config.go b/pkg/config/config.go index 74855f7..a3f9156 100755 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -5,7 +5,7 @@ type manager struct { } var Manager = manager{ - Switch: &Switch{}, + Switch: DefaultSwitch(), } func Reload() { diff --git a/pkg/config/point.go b/pkg/config/point.go index ed30f7f..5f4ed9d 100755 --- a/pkg/config/point.go +++ b/pkg/config/point.go @@ -134,22 +134,19 @@ func (ap *Point) Correct(obj *Point) { ap.Cert = obj.Cert } } - if ap.Protocol == "" { + if ap.Protocol == "" && obj != nil { ap.Protocol = obj.Protocol } if ap.Cert != nil { - if ap.Cert.Dir == "" { - ap.Cert.Dir = "." - } ap.Cert.Correct() } - if ap.Timeout == 0 { + if ap.Timeout == 0 && obj != nil { ap.Timeout = obj.Timeout } - if ap.Interface.Cost == 0 { + if ap.Interface.Cost == 0 && obj != nil { ap.Interface.Cost = obj.Interface.Cost } - if ap.Interface.IPMtu == 0 { + if ap.Interface.IPMtu == 0 && obj != nil { ap.Interface.IPMtu = obj.Interface.IPMtu } } diff --git a/pkg/config/switch.go b/pkg/config/switch.go index 66441d6..aed156e 100755 --- a/pkg/config/switch.go +++ b/pkg/config/switch.go @@ -97,6 +97,7 @@ func DefaultSwitch() *Switch { }, Listen: "0.0.0.0:10002", Cert: &Cert{}, + Crypt: &Crypt{}, } obj.Correct(nil) return obj @@ -141,16 +142,17 @@ func (s *Switch) Correct(obj *Switch) { libol.Debug("Proxy.Correct Http %v", s.Http) s.TokenFile = filepath.Join(s.ConfDir, "token") s.File = filepath.Join(s.ConfDir, "switch.json") - if s.Cert != nil { - s.Cert.Correct() - } else { + if s.Cert == nil { s.Cert = obj.Cert + } else { + s.Cert.Correct() + } + if s.Crypt == nil { + s.Crypt = obj.Crypt } perf := &s.Perf perf.Correct(DefaultPerf()) - if s.PassFile == "" { - s.PassFile = filepath.Join(s.ConfDir, "password") - } + s.PassFile = filepath.Join(s.ConfDir, "password") if s.Protocol == "" { s.Protocol = "tcp" } diff --git a/pkg/database/utils.go b/pkg/database/utils.go index 4addff9..c334853 100755 --- a/pkg/database/utils.go +++ b/pkg/database/utils.go @@ -15,5 +15,5 @@ func PrintError(result []ovsdb.OperationResult) { } func GenUUID() string { - return libol.GenRandom(32) + return libol.GenString(32) } diff --git a/pkg/libol/kcpsocket.go b/pkg/libol/kcpsocket.go index 9844cf1..95b299c 100755 --- a/pkg/libol/kcpsocket.go +++ b/pkg/libol/kcpsocket.go @@ -7,7 +7,7 @@ import ( ) type KcpConfig struct { - Block kcp.BlockCrypt + Block *BlockCrypt WinSize int // default 1024 DataShards int // default 10 ParityShards int // default 3 @@ -62,7 +62,7 @@ func NewKcpServer(listen string, cfg *KcpConfig) *KcpServer { func (k *KcpServer) Listen() (err error) { k.listener, err = kcp.ListenWithOptions( k.address, - k.kcpCfg.Block, + nil, k.kcpCfg.DataShards, k.kcpCfg.ParityShards) if err != nil { @@ -125,7 +125,10 @@ func NewKcpClient(addr string, cfg *KcpConfig) *KcpClient { } c := &KcpClient{ kcpCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), @@ -139,12 +142,15 @@ func NewKcpClientFromConn(conn net.Conn, cfg *KcpConfig) *KcpClient { } addr := conn.RemoteAddr().String() c := &KcpClient{ - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), } - c.updateConn(conn) + c.update(conn) return c } @@ -155,7 +161,7 @@ func (c *KcpClient) Connect() error { c.out.Info("KcpClient.Connect: kcp://%s", c.address) conn, err := kcp.DialWithOptions( c.address, - c.kcpCfg.Block, + nil, c.kcpCfg.DataShards, c.kcpCfg.DataShards) if err != nil { @@ -165,7 +171,7 @@ func (c *KcpClient) Connect() error { c.out.Warn("KcpClient.SetDSCP: ", err) } setConn(conn, c.kcpCfg) - c.SetConnection(conn) + c.Reset(conn) if c.listener.OnConnected != nil { _ = c.listener.OnConnected(c) } @@ -180,7 +186,7 @@ func (c *KcpClient) Close() { c.status = ClClosed } c.out.Debug("KcpClient.Close") - c.updateConn(nil) + c.update(nil) c.private = nil c.lock.Unlock() if c.listener.OnClose != nil { diff --git a/pkg/libol/message.go b/pkg/libol/message.go index 220bed9..87d1762 100755 --- a/pkg/libol/message.go +++ b/pkg/libol/message.go @@ -32,6 +32,8 @@ const ( SignReq = "sign= " PingReq = "ping= " PongResp = "pong: " + NegoReq = "nego= " + NegoResp = "nego: " ) func isControl(data []byte) bool { @@ -129,11 +131,14 @@ func NewFrameMessageFromBytes(buffer []byte) *FrameMessage { m.frame = m.buffer[HlSize:] m.total = len(m.frame) m.size = len(m.frame) + m.control = isControl(m.frame) + if m.control { + m.Decode() + } return &m } func (m *FrameMessage) Decode() bool { - m.control = isControl(m.frame) if m.control { if len(m.frame) < 2*EthDI { Warn("FrameMessage.Decode: too small message") @@ -233,6 +238,8 @@ func (c *ControlMessage) Encode() *FrameMessage { } type Messager interface { + Crypt() *BlockCrypt + SetCrypt(*BlockCrypt) Send(conn net.Conn, frame *FrameMessage) (int, error) Receive(conn net.Conn, max, min int) (*FrameMessage, error) Flush() @@ -240,11 +247,19 @@ type Messager interface { type StreamMessagerImpl struct { timeout time.Duration // ns for read and write deadline. - block kcp.BlockCrypt + block *BlockCrypt buffer []byte bufSize int // default is (1518 + 20+20+14) * 8 } +func (s *StreamMessagerImpl) SetCrypt(block *BlockCrypt) { + s.block = CopyBlockCrypt(block) +} + +func (s *StreamMessagerImpl) Crypt() *BlockCrypt { + return s.block +} + func (s *StreamMessagerImpl) Flush() { s.buffer = nil } @@ -410,10 +425,18 @@ func (s *StreamMessagerImpl) Receive(conn net.Conn, max, min int) (*FrameMessage type PacketMessagerImpl struct { timeout time.Duration // ns for read and write deadline - block kcp.BlockCrypt + block *BlockCrypt bufSize int // default is (1518 + 20+20+14) * 8 } +func (s *PacketMessagerImpl) SetCrypt(block *BlockCrypt) { + s.block = CopyBlockCrypt(block) +} + +func (s *PacketMessagerImpl) Crypt() *BlockCrypt { + return s.block +} + func (s *PacketMessagerImpl) Flush() { //TODO } @@ -479,3 +502,60 @@ func (s *PacketMessagerImpl) Receive(conn net.Conn, max, min int) (*FrameMessage frame.frame = tmp return frame, nil } + +type BlockCrypt struct { + kcp.BlockCrypt + algorithm string + key string +} + +func GetKcpBlock(algo string, key string) kcp.BlockCrypt { + var block kcp.BlockCrypt + + pass := make([]byte, 64) + if len(key) <= 64 { + copy(pass, key) + } else { + copy(pass, key[:64]) + } + + switch algo { + case "aes-128": + block, _ = kcp.NewAESBlockCrypt(pass[:16]) + case "aes-256": + block, _ = kcp.NewAESBlockCrypt(pass[:32]) + case "xor": + block, _ = kcp.NewSimpleXORBlockCrypt(pass) + default: + block, _ = kcp.NewNoneBlockCrypt(pass) + } + + return block +} + +func NewBlockCrypt(algo string, key string) *BlockCrypt { + if key == "" { + return nil + } + return &BlockCrypt{ + BlockCrypt: GetKcpBlock(algo, key), + algorithm: algo, + key: key, + } +} + +func CopyBlockCrypt(crypt *BlockCrypt) *BlockCrypt { + if crypt == nil { + return nil + } + return &BlockCrypt{ + BlockCrypt: GetKcpBlock(crypt.algorithm, crypt.key), + algorithm: crypt.algorithm, + key: crypt.key, + } +} + +func (b *BlockCrypt) Update(key string) { + b.key = key + b.BlockCrypt = GetKcpBlock(b.algorithm, b.key) +} diff --git a/pkg/libol/socket.go b/pkg/libol/socket.go index a6d928d..8f3640b 100755 --- a/pkg/libol/socket.go +++ b/pkg/libol/socket.go @@ -1,19 +1,22 @@ package libol import ( + "bytes" "net" "sync" "time" ) const ( - ClInit = 0x00 - ClConnected = 0x01 - ClUnAuth = 0x02 - ClAuth = 0x03 - ClConnecting = 0x04 - ClTerminal = 0x05 - ClClosed = 0x06 + ClInit = 0x00 + ClConnected = 0x01 + ClUnAuth = 0x02 + ClAuth = 0x03 + ClConnecting = 0x04 + ClTerminal = 0x05 + ClClosed = 0x06 + ClNegotiating = 0x07 + ClNegotiated = 0x08 ) type SocketStatus uint8 @@ -34,6 +37,10 @@ func (s SocketStatus) String() string { return "connecting" case ClTerminal: return "terminal" + case ClNegotiating: + return "negotiating" + case ClNegotiated: + return "negotiated" } return "" } @@ -77,6 +84,8 @@ type SocketClient interface { SetListener(listener ClientListener) SetTimeout(v int64) Out() *SubLogger + SetKey(key string) + Key() string } type StreamSocket struct { @@ -89,6 +98,7 @@ type StreamSocket struct { remoteAddr string localAddr string address string + Block *BlockCrypt } func (t *StreamSocket) LocalAddr() string { @@ -147,6 +157,25 @@ func (t *StreamSocket) ReadMsg() (*FrameMessage, error) { return frame, nil } +func (t *StreamSocket) SetKey(key string) { + if block := t.message.Crypt(); block != nil { + block.Update(key) + } +} + +func (t *StreamSocket) Key() string { + key := "" + if block := t.message.Crypt(); block != nil { + key = block.key + } + return key +} + +type SocketConfig struct { + Address string + Block *BlockCrypt +} + type SocketClientImpl struct { *StreamSocket lock sync.RWMutex @@ -158,22 +187,56 @@ type SocketClientImpl struct { timeout int64 // sec for read and write timeout } -func NewSocketClient(address string, message Messager) *SocketClientImpl { +func NewSocketClient(cfg SocketConfig, message Messager) *SocketClientImpl { return &SocketClientImpl{ StreamSocket: &StreamSocket{ maxSize: 1514, minSize: 15, message: message, statistics: NewSafeStrInt64(), - out: NewSubLogger(address), - remoteAddr: address, - address: address, + out: NewSubLogger(cfg.Address), + remoteAddr: cfg.Address, + address: cfg.Address, + Block: cfg.Block, }, newTime: time.Now().Unix(), status: ClInit, } } +func (s *SocketClientImpl) negotiate() error { + if s.Key() == "" { + return nil + } + key := GenLetters(64) + request := NewControlFrame(NegoReq, key) + if err := s.WriteMsg(request); err != nil { + return err + } + s.status = ClNegotiating + if reply, err := s.ReadMsg(); err == nil { + if reply.IsControl() { + action, params := reply.CmdAndParams() + if action != NegoResp { + return NewErr("wrong message type: %s", action) + } + if bytes.Compare(key, params) != 0 { + return NewErr("negotiate key failed: %s != %s", key, params) + } + if block := s.message.Crypt(); block != nil { + block.Update(string(key)) + } + s.status = ClNegotiated + return nil + } else { + Info("SocketClientImpl.negotiate %s", reply.String()) + } + return NewErr("wrong message type") + } else { + return err + } +} + // MUST IMPLEMENT func (s *SocketClientImpl) Connect() error { return nil @@ -265,7 +328,7 @@ func (s *SocketClientImpl) SetTimeout(v int64) { s.timeout = v } -func (s *SocketClientImpl) updateConn(conn net.Conn) { +func (s *SocketClientImpl) update(conn net.Conn) { if conn != nil { s.connection = conn s.connectedTime = time.Now().Unix() @@ -280,14 +343,21 @@ func (s *SocketClientImpl) updateConn(conn net.Conn) { s.remoteAddr = "" s.message.Flush() } - s.out.Event("SocketClientImpl.updateConn: %s %s", s.localAddr, s.remoteAddr) + if s.Block != nil { + s.message.SetCrypt(s.Block) + } + s.out.Event("SocketClientImpl.update: %s %s", s.localAddr, s.remoteAddr) } -func (s *SocketClientImpl) SetConnection(conn net.Conn) { +func (s *SocketClientImpl) Reset(conn net.Conn) { s.lock.Lock() defer s.lock.Unlock() - s.updateConn(conn) + s.update(conn) s.status = ClConnected + if err := s.negotiate(); err != nil { + s.out.Error("SocketClientImpl.Reset %s", err) + return + } } // MUST IMPLEMENT @@ -380,14 +450,48 @@ func (t *SocketServerImpl) OffClient(client SocketClient) { } } +func (t *SocketServerImpl) negotiate(client SocketClient) error { + if client.Key() == "" { + return nil + } + if request, err := client.ReadMsg(); err == nil { + if request.IsControl() { + client.SetStatus(ClNegotiated) + action, params := request.CmdAndParams() + if action == NegoReq { + Info("SocketServerImpl.negotiate %s", params) + reply := NewControlFrame(NegoResp, params) + if err := client.WriteMsg(reply); err != nil { + return err + } + client.SetKey(string(params)) + return nil + } + return NewErr("wrong message type: %s", action) + } else { + Info("SocketServerImpl.negotiate %s", request.String()) + } + return NewErr("wrong message type") + } else { + return err + } +} + func (t *SocketServerImpl) doOnClient(call ServerListener, client SocketClient) { Info("SocketServerImpl.doOnClient: +%s", client) _ = t.clients.Set(client.RemoteAddr(), client) if call.OnClient != nil { - _ = call.OnClient(client) - if call.ReadAt != nil { - Go(func() { t.Read(client, call.ReadAt) }) - } + Go(func() { + if err := t.negotiate(client); err != nil { + t.OffClient(client) + Warn("SocketServerImpl.doOnClient %s %s", client, err) + return + } + _ = call.OnClient(client) + if call.ReadAt != nil { + t.Read(client, call.ReadAt) + } + }) } } diff --git a/pkg/libol/tcpsocket.go b/pkg/libol/tcpsocket.go index 7d80c83..9cc15b7 100755 --- a/pkg/libol/tcpsocket.go +++ b/pkg/libol/tcpsocket.go @@ -2,14 +2,13 @@ package libol import ( "crypto/tls" - "github.com/xtaci/kcp-go/v5" "net" "time" ) type TcpConfig struct { Tls *tls.Config - Block kcp.BlockCrypt + Block *BlockCrypt Timeout time.Duration // ns RdQus int // per frames WrQus int // per frames @@ -97,8 +96,10 @@ type TcpClient struct { func NewTcpClient(addr string, cfg *TcpConfig) *TcpClient { t := &TcpClient{ tcpCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ - block: cfg.Block, + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), @@ -110,13 +111,15 @@ func NewTcpClientFromConn(conn net.Conn, cfg *TcpConfig) *TcpClient { addr := conn.RemoteAddr().String() t := &TcpClient{ tcpCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ - block: cfg.Block, + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), } - t.updateConn(conn) + t.update(conn) return t } @@ -136,7 +139,7 @@ func (t *TcpClient) Connect() error { if err != nil { return err } - t.SetConnection(conn) + t.Reset(conn) if t.listener.OnConnected != nil { _ = t.listener.OnConnected(t) } @@ -150,7 +153,7 @@ func (t *TcpClient) Close() { if t.status != ClTerminal { t.status = ClClosed } - t.updateConn(nil) + t.update(nil) t.private = nil t.lock.Unlock() if t.listener.OnClose != nil { diff --git a/pkg/libol/udpsocket.go b/pkg/libol/udpsocket.go index bf09acd..639d63c 100755 --- a/pkg/libol/udpsocket.go +++ b/pkg/libol/udpsocket.go @@ -1,13 +1,12 @@ package libol import ( - "github.com/xtaci/kcp-go/v5" "net" "time" ) type UdpConfig struct { - Block kcp.BlockCrypt + Block *BlockCrypt Timeout time.Duration // ns Clients int RdQus int // per frames @@ -97,9 +96,11 @@ func NewUdpClient(addr string, cfg *UdpConfig) *UdpClient { } c := &UdpClient{ udpCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &PacketMessagerImpl{ + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &PacketMessagerImpl{ timeout: cfg.Timeout, - block: cfg.Block, bufSize: cfg.RdQus * MaxFrame, }), } @@ -112,13 +113,15 @@ func NewUdpClientFromConn(conn net.Conn, cfg *UdpConfig) *UdpClient { } addr := conn.RemoteAddr().String() c := &UdpClient{ - SocketClientImpl: NewSocketClient(addr, &PacketMessagerImpl{ + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &PacketMessagerImpl{ timeout: cfg.Timeout, - block: cfg.Block, bufSize: cfg.RdQus * MaxFrame, }), } - c.updateConn(conn) + c.update(conn) return c } @@ -131,7 +134,7 @@ func (c *UdpClient) Connect() error { if err != nil { return err } - c.SetConnection(conn) + c.Reset(conn) if c.listener.OnConnected != nil { _ = c.listener.OnConnected(c) } @@ -146,7 +149,7 @@ func (c *UdpClient) Close() { c.status = ClClosed } c.out.Info("UdpClient.Close") - c.updateConn(nil) + c.update(nil) c.private = nil c.lock.Unlock() if c.listener.OnClose != nil { diff --git a/pkg/libol/utils.go b/pkg/libol/utils.go index 6c9e4dd..0673f53 100755 --- a/pkg/libol/utils.go +++ b/pkg/libol/utils.go @@ -23,17 +23,28 @@ import ( const LeaseTime = "2006-01-02T15" const SimpleTime = "2006-01-02 15:04:05" -func GenRandom(n int) string { - letters := []byte("0123456789abcdefghijklmnopqrstuvwxyz") +var Letters = []byte("0123456789abcdefghijklmnopqrstuvwxyz") + +func GenString(n int) string { buffer := make([]byte, n) rand.Seed(time.Now().UnixNano()) for i := range buffer { - buffer[i] = letters[rand.Int63()%int64(len(letters))] + buffer[i] = Letters[rand.Int63()%int64(len(Letters))] } - buffer[0] = letters[rand.Int63()%26+10] + buffer[0] = Letters[rand.Int63()%26+10] return string(buffer) } +func GenLetters(n int) []byte { + buffer := make([]byte, n) + rand.Seed(time.Now().UnixNano()) + for i := range buffer { + buffer[i] = Letters[rand.Int63()%int64(len(Letters))] + } + buffer[0] = Letters[rand.Int63()%26+10] + return buffer +} + func GenEthAddr(n int) []byte { if n == 0 { n = 6 diff --git a/pkg/libol/websocket.go b/pkg/libol/websocket.go index f0706cf..373576d 100755 --- a/pkg/libol/websocket.go +++ b/pkg/libol/websocket.go @@ -3,7 +3,6 @@ package libol import ( "crypto/tls" "crypto/x509" - "github.com/xtaci/kcp-go/v5" "golang.org/x/net/websocket" "io/ioutil" "net" @@ -36,7 +35,7 @@ type CertConfig struct { type WebConfig struct { Cert *CertConfig - Block kcp.BlockCrypt + Block *BlockCrypt Timeout time.Duration // ns RdQus int // per frames WrQus int // per frames @@ -132,8 +131,10 @@ type WebClient struct { func NewWebClient(addr string, cfg *WebConfig) *WebClient { t := &WebClient{ webCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ - block: cfg.Block, + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), @@ -146,14 +147,16 @@ func NewWebClientFromConn(conn net.Conn, cfg *WebConfig) *WebClient { addr := conn.RemoteAddr().String() t := &WebClient{ webCfg: cfg, - SocketClientImpl: NewSocketClient(addr, &StreamMessagerImpl{ - block: cfg.Block, + SocketClientImpl: NewSocketClient(SocketConfig{ + Address: addr, + Block: cfg.Block, + }, &StreamMessagerImpl{ timeout: cfg.Timeout, bufSize: cfg.RdQus * MaxFrame, }), done: make(chan bool, 2), } - t.updateConn(conn) + t.update(conn) return t } @@ -197,7 +200,7 @@ func (t *WebClient) Connect() error { if err != nil { return err } - t.SetConnection(conn) + t.Reset(conn) if t.listener.OnConnected != nil { _ = t.listener.OnConnected(t) } @@ -211,7 +214,7 @@ func (t *WebClient) Close() { if t.status != ClTerminal { t.status = ClClosed } - t.updateConn(nil) + t.update(nil) t.done <- true t.private = nil t.lock.Unlock() diff --git a/pkg/switch/http.go b/pkg/switch/http.go index b2521ec..a550629 100755 --- a/pkg/switch/http.go +++ b/pkg/switch/http.go @@ -135,7 +135,7 @@ func (h *Http) LoadToken() { } } if token == "" { - token = libol.GenRandom(32) + token = libol.GenString(32) } h.SetToken(token) } diff --git a/pkg/switch/openlan.go b/pkg/switch/openlan.go index 64d785c..0b24ffe 100755 --- a/pkg/switch/openlan.go +++ b/pkg/switch/openlan.go @@ -276,7 +276,7 @@ func (w *OpenLANWorker) UpTime() int64 { func (w *OpenLANWorker) AddLink(c *co.Point) { br := w.cfg.Bridge - uuid := libol.GenRandom(13) + uuid := libol.GenString(13) c.Alias = w.alias c.Network = w.cfg.Name diff --git a/pkg/switch/switch.go b/pkg/switch/switch.go index 7cb8847..4840f7c 100755 --- a/pkg/switch/switch.go +++ b/pkg/switch/switch.go @@ -15,15 +15,17 @@ import ( ) func GetSocketServer(s *co.Switch) libol.SocketServer { + crypt := s.Crypt + block := libol.NewBlockCrypt(crypt.Algo, crypt.Secret) switch s.Protocol { case "kcp": c := libol.NewKcpConfig() - c.Block = co.GetBlock(s.Crypt) + c.Block = block c.Timeout = time.Duration(s.Timeout) * time.Second return libol.NewKcpServer(s.Listen, c) case "tcp": c := &libol.TcpConfig{ - Block: co.GetBlock(s.Crypt), + Block: block, Timeout: time.Duration(s.Timeout) * time.Second, RdQus: s.Queue.SockRd, WrQus: s.Queue.SockWr, @@ -31,13 +33,13 @@ func GetSocketServer(s *co.Switch) libol.SocketServer { return libol.NewTcpServer(s.Listen, c) case "udp": c := &libol.UdpConfig{ - Block: co.GetBlock(s.Crypt), + Block: block, Timeout: time.Duration(s.Timeout) * time.Second, } return libol.NewUdpServer(s.Listen, c) case "ws": c := &libol.WebConfig{ - Block: co.GetBlock(s.Crypt), + Block: block, Timeout: time.Duration(s.Timeout) * time.Second, RdQus: s.Queue.SockRd, WrQus: s.Queue.SockWr, @@ -45,7 +47,7 @@ func GetSocketServer(s *co.Switch) libol.SocketServer { return libol.NewWebServer(s.Listen, c) case "wss": c := &libol.WebConfig{ - Block: co.GetBlock(s.Crypt), + Block: block, Timeout: time.Duration(s.Timeout) * time.Second, RdQus: s.Queue.SockRd, WrQus: s.Queue.SockWr, @@ -59,7 +61,7 @@ func GetSocketServer(s *co.Switch) libol.SocketServer { return libol.NewWebServer(s.Listen, c) default: c := &libol.TcpConfig{ - Block: co.GetBlock(s.Crypt), + Block: block, Timeout: time.Duration(s.Timeout) * time.Second, RdQus: s.Queue.SockRd, WrQus: s.Queue.SockWr, @@ -662,7 +664,7 @@ func (v *Switch) FreeTap(dev network.Taper) error { func (v *Switch) UUID() string { if v.uuid == "" { - v.uuid = libol.GenRandom(13) + v.uuid = libol.GenString(13) } return v.uuid }