mirror of
https://github.com/luscis/openlan.git
synced 2025-09-26 20:41:29 +08:00
fea: socket: support to negotiate key
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
|
||||
|
@@ -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)},
|
||||
},
|
||||
|
@@ -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
|
||||
|
@@ -9,6 +9,7 @@ func InArray(data []int) {
|
||||
data[0] = 0x04
|
||||
fmt.Println(data)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a = []int{1, 2, 3}
|
||||
|
||||
|
@@ -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()
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ type manager struct {
|
||||
}
|
||||
|
||||
var Manager = manager{
|
||||
Switch: &Switch{},
|
||||
Switch: DefaultSwitch(),
|
||||
}
|
||||
|
||||
func Reload() {
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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"
|
||||
}
|
||||
|
@@ -15,5 +15,5 @@ func PrintError(result []ovsdb.OperationResult) {
|
||||
}
|
||||
|
||||
func GenUUID() string {
|
||||
return libol.GenRandom(32)
|
||||
return libol.GenString(32)
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -135,7 +135,7 @@ func (h *Http) LoadToken() {
|
||||
}
|
||||
}
|
||||
if token == "" {
|
||||
token = libol.GenRandom(32)
|
||||
token = libol.GenString(32)
|
||||
}
|
||||
h.SetToken(token)
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user