Commit 51b0ab0a authored by wei.xuan's avatar wei.xuan

Merge branch 'getty' into 'master'

feat:getty

See merge request !4
parents ee78d98f fb303f42
...@@ -3,7 +3,7 @@ export GOPROXY="https://goproxy.cn,https://goproxy.io,direct" ...@@ -3,7 +3,7 @@ export GOPROXY="https://goproxy.cn,https://goproxy.io,direct"
LDFLAGS := -s -w LDFLAGS := -s -w
DATE=$(shell date +"%Y-%m-%d") DATE=$(shell date +"%Y-%m-%d")
BUILDINFO := -X main.Version=v0.0.4 -X main.Date=$(DATE) BUILDINFO := -X main.Version=v0.0.5 -X main.Date=$(DATE)
all: all:
env CGO_ENABLED=0 go build -trimpath -ldflags '-w -s $(BUILDINFO)' -o bin/majora env CGO_ENABLED=0 go build -trimpath -ldflags '-w -s $(BUILDINFO)' -o bin/majora
......
...@@ -11,9 +11,12 @@ import ( ...@@ -11,9 +11,12 @@ import (
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"os/signal"
"runtime" "runtime"
"syscall"
"time" "time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/client" "virjar.com/majora-go/client"
"virjar.com/majora-go/common" "virjar.com/majora-go/common"
"virjar.com/majora-go/infra" "virjar.com/majora-go/infra"
...@@ -52,9 +55,11 @@ func init() { ...@@ -52,9 +55,11 @@ func init() {
} }
func initial(cfg *model.Configure) { func initial(cfg *model.Configure) {
_ = getty.SetLoggerCallerDisable()
_ = getty.SetLoggerLevel(getty.LoggerLevelDebug)
logger.SetLogLevel(cfg.LogLevel) logger.SetLogLevel(cfg.LogLevel)
addr := fmt.Sprintf("127.0.0.1:%d", cfg.PprofPort) addr := fmt.Sprintf("127.0.0.1:%d", cfg.PprofPort)
logger.Info().Msgf("enable pprof: %s", addr) getty.GetLogger().Infof("enable pprof: %s", addr)
if cfg.PprofPort > 0 { if cfg.PprofPort > 0 {
go func() { go func() {
log.Fatal(http.ListenAndServe(addr, nil)) log.Fatal(http.ListenAndServe(addr, nil))
...@@ -68,7 +73,7 @@ func initial(cfg *model.Configure) { ...@@ -68,7 +73,7 @@ func initial(cfg *model.Configure) {
return net.Dial("udp", dnsServer) return net.Dial("udp", dnsServer)
}, },
} }
logger.Info().Msgf("use custom dns server %s", dnsServer) getty.GetLogger().Infof("use custom dns server %s", dnsServer)
} }
if !cfg.DisableUpdate { if !cfg.DisableUpdate {
...@@ -97,10 +102,11 @@ func cli() { ...@@ -97,10 +102,11 @@ func cli() {
parseFromCmd(cfg) parseFromCmd(cfg)
} }
initial(cfg) initial(cfg)
logger.Info().Msgf("current Version %s, build at %s", Version, Date)
logger.Info().Msgf("hostinfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH) getty.GetLogger().Infof("current Version %s, build at %s", Version, Date)
getty.GetLogger().Infof("hostinfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH)
cfgInfo, _ := json.Marshal(cfg) cfgInfo, _ := json.Marshal(cfg)
logger.Info().Msgf("config info:%s", string(cfgInfo)) getty.GetLogger().Infof("config info:%s", string(cfgInfo))
client.NewClientWithConf(cfg) client.NewClientWithConf(cfg)
} }
...@@ -110,5 +116,16 @@ func main() { ...@@ -110,5 +116,16 @@ func main() {
fmt.Println(Version) fmt.Println(Version)
os.Exit(0) os.Exit(0)
} }
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
cli() cli()
}()
select {
case <-sigs:
time.Sleep(time.Second * 3)
getty.GetLogger().Info("main process exit...")
}
} }
package client package client
import ( import (
"bufio"
"errors"
"io"
"net" "net"
"sync" "sync"
"sync/atomic"
"virjar.com/majora-go/common" "github.com/adamweixuan/getty"
"virjar.com/majora-go/logger"
"virjar.com/majora-go/model" "virjar.com/majora-go/model"
"virjar.com/majora-go/protocol"
) )
type Client struct { type Client struct {
config *model.Configure config *model.Configure
localAddr net.Addr localAddr net.Addr
natTunnel atomic.Value natTunnel getty.Client
Codec protocol.ICodec
connStore sync.Map connStore sync.Map
} }
...@@ -39,8 +32,6 @@ func NewCli(cfg *model.Configure) *Client { ...@@ -39,8 +32,6 @@ func NewCli(cfg *model.Configure) *Client {
client := &Client{ client := &Client{
config: cfg, config: cfg,
localAddr: localAddr, localAddr: localAddr,
natTunnel: atomic.Value{},
Codec: protocol.Codec,
connStore: sync.Map{}, connStore: sync.Map{},
} }
...@@ -49,64 +40,4 @@ func NewCli(cfg *model.Configure) *Client { ...@@ -49,64 +40,4 @@ func NewCli(cfg *model.Configure) *Client {
func (client *Client) StartUp() { func (client *Client) StartUp() {
client.connect() client.connect()
client.register()
client.handleNatEvent()
}
func (client *Client) register() {
packet := protocol.TypeRegister.CreatePacket()
packet.Extra = client.config.ClientID
extraMap := make(map[string]string, 1)
extraMap[common.ExtrakeyUser] = client.config.Extra.Account
packet.Data = protocol.EncodeExtra(extraMap)
if err := client.WriteAndFlush(packet); err != nil {
logger.Error().Msgf("register to nat server with error %s", err.Error())
} else {
logger.Info().Msgf("client %s register to nat server %s success", client.config.ClientID, client.config.TunnelAddr)
}
if client.config.Redial.Invalid() {
client.Redial()
}
}
func (client *Client) handleNatEvent() {
for {
conn, ok := client.natTunnel.Load().(net.Conn)
if !ok {
logger.Error().Msgf("[core] tunnel server is invalid, reconnect...")
client.reConnect()
continue
}
reader := bufio.NewReader(conn)
majoraPacket, err := client.Codec.Decode(reader)
if errors.Is(err, io.EOF) {
// 清理本地session
client.reConnect()
continue
}
if majoraPacket == nil || err != nil {
if err != nil {
logger.Error().Msgf("decode_error %s->%+v", conn.RemoteAddr(), err)
}
client.reConnect()
continue
}
logger.Debug().Msgf("receive packet type %s", majoraPacket.Ttype.ToString())
switch majoraPacket.Ttype {
case protocol.TypeHeartbeat:
client.handleHeartbeatMessage()
case protocol.TypeConnect:
client.handleConnect(majoraPacket)
case protocol.TypeTransfer:
client.handleTransfer(majoraPacket)
case protocol.TypeDisconnect:
client.handleDisconnectMessage(majoraPacket)
case protocol.TypeControl:
client.handleControlMessage(majoraPacket)
case protocol.TypeDestroy:
client.handleDestroyMessage()
}
}
} }
package client
import (
"bytes"
"encoding/binary"
"errors"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common"
"virjar.com/majora-go/protocol"
)
var (
PkgCodec = &PacketCodec{}
)
type PacketCodec struct {
}
func (p *PacketCodec) Read(session getty.Session, data []byte) (interface{}, int, error) {
getty.GetLogger().Debugf("[PacketCodec] %s->%d", string(data), len(data))
if len(data) < common.MagicSize+common.FrameSize {
return nil, 0, nil
}
getty.GetLogger().Debugf("[PacketCodec] read magic %+v", binary.BigEndian.Uint64(data[0:8]))
if !common.ReadMagic(data[0:common.MagicSize]) {
return nil, 0, common.ErrInvalidMagic
}
reader := bytes.NewBuffer(data[common.MagicSize:])
frameLen, err := common.ReadInt32(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] frameLen error %+v", err)
return nil, 0, common.ErrInvalidSize
}
getty.GetLogger().Debugf("[PacketCodec] read frameLen %d", frameLen)
// type
msgType, err := common.ReadByte(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read type error %+v", err)
return nil, 0, common.ErrInvalidSize
}
getty.GetLogger().Debugf("[PacketCodec] read msgType %+v", msgType)
pack := &protocol.MajoraPacket{}
pack.Ttype = protocol.MajoraPacketType(msgType)
// num
pack.SerialNumber, err = common.ReadInt64(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read num error %+v", err)
return nil, 0, common.ErrInvalidSize
}
getty.GetLogger().Debugf("[PacketCodec] read SerialNumber %d", pack.SerialNumber)
// extra size
extraSize, err := common.ReadByte(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read extra size error %+v", err)
return nil, 0, common.ErrInvalidSize
}
extra, err := common.ReadN(int(extraSize), reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read extra error %+v", err)
return nil, 0, common.ErrInvalidSize
}
pack.Extra = string(extra)
getty.GetLogger().Debugf("[PacketCodec] read extra %s", pack.Extra)
// dataFrame
dataSize := int(frameLen) - common.TypeSize - common.SerialNumberSize - common.ExtraSize - int(extraSize)
if dataSize < 0 {
getty.GetLogger().Errorf("[PacketCodec] read frameLen error %+v", err)
return nil, 0, common.ErrInvalidSize
}
if dataSize > 0 {
data, err := common.ReadN(dataSize, reader)
if err != nil {
getty.GetLogger().Errorf("read data error %+v", err)
}
pack.Data = data
}
getty.GetLogger().Debugf("[PacketCodec] read response %d", int(frameLen+12))
return pack, int(frameLen + 12), nil
}
func (p *PacketCodec) Write(session getty.Session, packet interface{}) ([]byte, error) {
majoraPkt, ok := packet.(*protocol.MajoraPacket)
if !ok {
return nil, errors.New("invalid packet")
}
return protocol.Codec.Encode(majoraPkt), nil
}
package client
import (
"fmt"
"net"
"runtime"
"sync"
"time"
"virjar.com/majora-go/common"
"virjar.com/majora-go/infra"
"virjar.com/majora-go/logger"
"virjar.com/majora-go/protocol"
)
func (client *Client) connect() {
hostPort := client.config.TunnelAddr
if len(hostPort) == 0 {
panic("invalid nat host/port info")
}
dialer := net.Dialer{
Timeout: common.ConnTimeout,
}
if client.localAddr != nil {
dialer.LocalAddr = client.localAddr
}
conn, err := dialer.Dial(common.TCP, hostPort)
if err != nil || conn == nil {
panic(fmt.Sprintf("connect to nathost %s with err %s", hostPort, err.Error()))
}
if dialer.LocalAddr != nil {
logger.Info().Msgf("connect from %s to nathost %s success ...", dialer.LocalAddr.String(), hostPort)
} else {
logger.Info().Msgf("connect to nathost %s success ...", hostPort)
}
client.natTunnel.Store(conn)
}
func (client *Client) reConnect() {
client.cleanSession()
// 已经check 过
hostPort := client.config.TunnelAddr
dialer := net.Dialer{
Timeout: common.ConnTimeout,
}
if client.localAddr != nil {
dialer.LocalAddr = client.localAddr
}
var (
conn net.Conn
err error
)
for {
conn, err = dialer.Dial(common.TCP, hostPort)
if err != nil || conn == nil {
// 不断重试
logger.Info().Msgf("reconnect to nathost with error %+v ...", err)
time.Sleep(client.config.ReconnInterval)
} else {
break
}
}
logger.Info().Msgf("%s reconnect to nathost %s success ...", client.config.ClientID, hostPort)
client.natTunnel.Store(conn)
client.connStore = sync.Map{}
client.register()
}
func (client *Client) Redial() {
go func() {
var timer *time.Timer
for {
if timer == nil {
timer = time.NewTimer(client.config.Redial.RedialDuration)
} else {
timer.Reset(client.config.Redial.RedialDuration)
}
<-timer.C
majoraPacket := protocol.TypeOffline.CreatePacket()
if err := client.WriteAndFlush(majoraPacket); err != nil {
logger.Warn().Msgf("flush to nat server error %s", err.Error())
}
logger.Info().Msgf("====================redial start ==============")
time.Sleep(client.config.Redial.WaitTime)
infra.Redial(client.config)
client.reConnect()
}
}()
}
func (client *Client) cleanSession() {
logger.Info().Msgf("cleanSession [before] thread cnt %d", runtime.NumGoroutine())
client.connStore.Range(func(key, value interface{}) bool {
serialId, _ := key.(int64)
conn, ok := value.(net.Conn)
if ok && conn != nil {
if err := conn.Close(); err != nil {
logger.Error().Msgf("cleanSession close %s with error %s", conn.RemoteAddr(), err)
} else {
logger.Error().Msgf("cleanSession close %d->s with success", serialId, conn.RemoteAddr())
}
}
client.connStore.Delete(serialId)
return true
})
logger.Info().Msgf("cleanSession [after] thread cnt %d", runtime.NumGoroutine())
}
...@@ -5,7 +5,9 @@ import ( ...@@ -5,7 +5,9 @@ import (
"fmt" "fmt"
"net" "net"
"strings" "strings"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common" "virjar.com/majora-go/common"
"virjar.com/majora-go/logger" "virjar.com/majora-go/logger"
"virjar.com/majora-go/protocol" "virjar.com/majora-go/protocol"
...@@ -13,38 +15,29 @@ import ( ...@@ -13,38 +15,29 @@ import (
var ( var (
HeartbeatPacket = protocol.TypeHeartbeat.CreatePacket() HeartbeatPacket = protocol.TypeHeartbeat.CreatePacket()
DisconnectPacket = protocol.TypeDisconnect.CreatePacket() OfflinePacket = protocol.TypeOffline.CreatePacket()
) )
// todo 心跳超时检测 func (client *Client) handleHeartbeat(session getty.Session) {
func (client *Client) handleHeartbeatMessage() {
go func() { go func() {
logger.Debug().Msg("receive heartbeat message from nat server") if _, _, err := session.WritePkg(HeartbeatPacket, time.Second*3); err != nil {
if err := client.WriteAndFlush(HeartbeatPacket); err != nil { getty.GetLogger().Errorf("handleHeartbeat error %+v %v->%v", err, session.IsClosed(), session.GetActive())
logger.Error().Msgf("flush heart beat message error %s", err.Error()) } else {
getty.GetLogger().Infof("handleHeartbeat success %v->%v", session.IsClosed(), session.GetActive())
} }
}() }()
} }
func (client *Client) handleConnect(packet *protocol.MajoraPacket) { func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty.Session) {
go func(packet *protocol.MajoraPacket) { go func(packet *protocol.MajoraPacket) {
if len(packet.Extra) == 0 {
client.closeVirtualConnection(packet, "empty extra")
return
}
hostPort := strings.Split(packet.Extra, ":") hostPort := strings.Split(packet.Extra, ":")
if len(hostPort) != 2 { if len(packet.Extra) == 0 || len(hostPort) != 2 {
client.closeVirtualConnection(packet, "invalid extra "+packet.Extra) getty.GetLogger().Errorf("invalid extra %s", packet.Extra)
client.closeVirtualConnection(session, packet.SerialNumber)
return return
} }
var (
conn net.Conn
err error
)
addr := fmt.Sprintf("%s:%s", hostPort[0], hostPort[1]) addr := fmt.Sprintf("%s:%s", hostPort[0], hostPort[1])
dialer := net.Dialer{ dialer := net.Dialer{
...@@ -55,105 +48,91 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket) { ...@@ -55,105 +48,91 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket) {
dialer.LocalAddr = client.localAddr dialer.LocalAddr = client.localAddr
} }
conn, err = dialer.Dial(common.TCP, addr) conn, err := dialer.Dial(common.TCP, addr)
if err != nil { if err != nil {
client.closeVirtualConnection(packet, "connect to target host error "+err.Error()) getty.GetLogger().Errorf("connect to %s->%s", addr, err.Error())
client.closeVirtualConnection(session, packet.SerialNumber)
return return
} }
logger.Info().Msgf("connect success to %d->%s ", packet.SerialNumber, hostPort) getty.GetLogger().Infof("connect success to %d->%s ", packet.SerialNumber, addr)
client.AddConnection(packet, conn, addr) client.AddConnection(packet, conn, addr)
majoraPacket := protocol.TypeConnectReady.CreatePacket() majoraPacket := protocol.TypeConnectReady.CreatePacket()
majoraPacket.SerialNumber = packet.SerialNumber majoraPacket.SerialNumber = packet.SerialNumber
majoraPacket.Extra = client.config.ClientID majoraPacket.Extra = client.config.ClientID
if _, _, err := session.WritePkg(majoraPacket, time.Second*30); err != nil {
if err := client.WriteAndFlush(majoraPacket); err != nil { getty.GetLogger().Errorf("write pkg to nat server with error %s", err.Error())
logger.Error().Msgf("handleConnect message error %d->%s", packet.SerialNumber, err.Error()) client.closeVirtualConnection(session, packet.SerialNumber)
// close && clean
_ = conn.Close()
client.removeConnection(packet, "client:"+err.Error())
return return
} }
client.handleConnection(conn, packet) client.handleUpStream(conn, packet, session)
}(packet) }(packet)
} }
func (client *Client) WriteAndFlush(packet *protocol.MajoraPacket) error { func (client *Client) handleTransfer(packet *protocol.MajoraPacket, session getty.Session) {
writer := bufio.NewWriter(client.natTunnel.Load().(net.Conn))
encode := client.Codec.Encode(packet)
if _, err := writer.Write(encode); err != nil {
logger.Warn().Msgf("write to nat server error err:%+v", err)
return err
}
return writer.Flush()
}
func (client *Client) WriteAndFlushBytes(packets []byte) error {
writer := bufio.NewWriter(client.natTunnel.Load().(net.Conn))
if _, err := writer.Write(packets); err != nil {
logger.Warn().Msgf("write to nat server error err:%+v", err)
return err
}
return writer.Flush()
}
func (client *Client) handleTransfer(packet *protocol.MajoraPacket) {
go func(packet *protocol.MajoraPacket) { go func(packet *protocol.MajoraPacket) {
conn, ok := client.GetConnection(packet, "handleTransfer") load, ok := client.connStore.Load(packet.SerialNumber)
if !ok { if !ok {
client.closeVirtualConnection(packet, "handleTransfer") getty.GetLogger().Errorf("fatal can not find connection for %d", packet.SerialNumber)
client.closeVirtualConnection(session, packet.SerialNumber)
return return
} }
writer := bufio.NewWriter(conn) conn := load.(net.Conn)
flush(client, writer, packet) cnt, err := conn.Write(packet.Data)
logger.Debug().Msgf("handleTransfer success %d->%+v", packet.SerialNumber, string(packet.Data))
}(packet)
}
func flush(client *Client, writer *bufio.Writer, packet *protocol.MajoraPacket) { if err != nil {
if cnt, err := writer.Write(packet.Data); err != nil { getty.GetLogger().Errorf("write to upstream fail for %d->", packet.SerialNumber, err)
logger.Warn().Msgf("write with error cnt=%d|err=%+v", cnt, err) client.closeVirtualConnection(session, packet.SerialNumber)
client.removeConnection(packet, "write_error:"+err.Error()) return
} }
if err := writer.Flush(); err != nil { if cnt != len(packet.Data) {
logger.Warn().Msgf("flush with error err=%+v", err) getty.GetLogger().Errorf("write not all data for %d->expect->%d/%d",
client.removeConnection(packet, "write_error:"+err.Error()) packet.SerialNumber, len(packet.Data), cnt)
client.closeVirtualConnection(session, packet.SerialNumber)
return
} }
getty.GetLogger().Debugf("handleTransfer success %d->%+v", packet.SerialNumber, string(packet.Data))
}(packet)
} }
func (client *Client) handleConnection(conn net.Conn, packet *protocol.MajoraPacket) { func (client *Client) handleUpStream(conn net.Conn, packet *protocol.MajoraPacket, session getty.Session) {
logger.Info().Msgf("serialNum %d -> handleConnection start...", packet.SerialNumber) getty.GetLogger().Infof("serialNum %d -> handleUpStream start...", packet.SerialNumber)
reader := bufio.NewReader(conn) reader := bufio.NewReader(conn)
for { for {
if _, err := reader.Peek(1); err != nil { if _, err := reader.Peek(1); err != nil {
logger.Error().Msgf("%d -> handleConnection peek with error:%+v", packet.SerialNumber, err) getty.GetLogger().Warnf("%d -> handleUpStream peek with error:%s", packet.SerialNumber, err.Error())
client.removeConnection(packet, fmt.Sprintf("peek:%s", err)) client.OnClose(session, conn, packet.SerialNumber)
break break
} }
bufsize := reader.Buffered() bufsize := reader.Buffered()
logger.Debug().Msgf("bufsize %d", bufsize) getty.GetLogger().Debugf("bufsize %d", bufsize)
buf := make([]byte, bufsize) buf := make([]byte, bufsize)
_, err := reader.Read(buf) _, err := reader.Read(buf)
if err != nil { if err != nil {
logger.Error().Msgf("handleConnection read with error:%d->%+v", packet.SerialNumber, err) getty.GetLogger().Errorf("handleUpStream read with error:%d->%+v", packet.SerialNumber, err)
client.OnClose(session, conn, packet.SerialNumber)
break break
} }
pack := protocol.TypeTransfer.CreatePacket() pack := protocol.TypeTransfer.CreatePacket()
pack.Data = buf pack.Data = buf
pack.SerialNumber = packet.SerialNumber pack.SerialNumber = packet.SerialNumber
if err = client.WriteAndFlush(pack); err != nil {
logger.Error().Msgf("write to nat server error %d->%+v", packet.SerialNumber, err) if _, _, err := session.WritePkg(pack, time.Second*10); err != nil {
getty.GetLogger().Debugf("handleUpStream fail %d->%+v", packet.SerialNumber, err.Error())
client.OnClose(session, conn, packet.SerialNumber)
break
} else {
getty.GetLogger().Debugf("handleUpStream success %d->%+v", packet.SerialNumber, string(packet.Data))
} }
logger.Debug().Msgf("handleConnection success %d->%+v", packet.SerialNumber, string(packet.Data))
} }
} }
func (client *Client) handleDisconnectMessage(packet *protocol.MajoraPacket) { func (client *Client) handleDisconnectMessage(session getty.Session, packet *protocol.MajoraPacket) {
go func() { go func() {
client.removeConnection(packet, "from_server") if conn, ok := client.connStore.Load(packet.SerialNumber); ok {
client.OnClose(session, conn.(net.Conn), packet.SerialNumber)
}
}() }()
} }
...@@ -166,66 +145,51 @@ func (client *Client) handleControlMessage(_ *protocol.MajoraPacket) { ...@@ -166,66 +145,51 @@ func (client *Client) handleControlMessage(_ *protocol.MajoraPacket) {
// handleDestroyMessage 是直接关闭nat server ? // handleDestroyMessage 是直接关闭nat server ?
func (client *Client) handleDestroyMessage() { func (client *Client) handleDestroyMessage() {
go func() { go func() {
conn, ok := client.natTunnel.Load().(net.Conn) client.natTunnel.Close()
if ok && conn != nil {
_ = conn.Close()
}
}() }()
} }
func (client *Client) AddConnection(packet *protocol.MajoraPacket, conn net.Conn, addr string) { func (client *Client) AddConnection(packet *protocol.MajoraPacket, conn net.Conn, addr string) {
client.connStore.Store(packet.SerialNumber, conn) client.connStore.Store(packet.SerialNumber, conn)
logger.Info().Msgf("create connection for %d->%s", packet.SerialNumber, addr) getty.GetLogger().Infof("create connection for %d->%s", packet.SerialNumber, addr)
} }
// removeConnection 1. 本地缓存删除 2. 关闭连接 3. 通知natserver // OnClose 1. 本地缓存删除 2. 关闭连接 3. 通知natserver
func (client *Client) removeConnection(packet *protocol.MajoraPacket, reason string) { func (client *Client) OnClose(netSession getty.Session, upStreamSession net.Conn, serialNumber int64) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
logger.Error().Msgf("removeConnection panic %+v", err) getty.GetLogger().Errorf("OnClose %+v", err)
} }
}() }()
// delete from local cache client.closeVirtualConnection(netSession, serialNumber)
conn, ok := client.GetConnection(packet, "remove:"+reason) client.connStore.Delete(serialNumber)
if ok { _ = upStreamSession.Close()
client.connStore.Delete(packet.SerialNumber)
// 直接关闭是否就可以 主动断开 是否有剩余数据已经意义不大了
_ = conn.Close()
logger.Info().Msgf("removeConnection target connection %d, reason %s", packet.SerialNumber, reason)
majoraPacket := protocol.TypeDisconnect.CreatePacket()
majoraPacket.SerialNumber = packet.SerialNumber
majoraPacket.Data = []byte(client.config.ClientID)
if err := client.WriteAndFlush(majoraPacket); err != nil {
logger.Warn().Msgf("flush to nat server error %s", err.Error())
}
}
} }
func (client *Client) GetConnection(packet *protocol.MajoraPacket, step string) (conn net.Conn, ok bool) { //closeVirtualConnection disconnect to server
load, ok := client.connStore.Load(packet.SerialNumber) func (client *Client) closeVirtualConnection(session getty.Session, serialNumber int64) {
getty.GetLogger().Infof("[closeVirtualConnection] %d session status:%v", serialNumber, session.IsClosed())
// 没有的话 可能是服务端未感知到端上的连接已断开了 if !session.IsClosed() {
// 是否需要主动创建一个
if !ok || load == nil {
client.closeVirtualConnection(packet, fmt.Sprintf("get %d->%s", packet.SerialNumber, step))
return nil, false
}
conn, ok = load.(net.Conn)
return
}
func (client *Client) closeVirtualConnection(packet *protocol.MajoraPacket, msg string) {
logger.Warn().Msgf("disconnect to server %d->%s", packet.SerialNumber, msg)
majoraPacket := protocol.TypeDisconnect.CreatePacket() majoraPacket := protocol.TypeDisconnect.CreatePacket()
majoraPacket.SerialNumber = packet.SerialNumber majoraPacket.SerialNumber = serialNumber
ll := len(msg) majoraPacket.Extra = client.config.ClientID
if ll >= 127 { if _, _, err := session.WritePkg(majoraPacket, time.Second*30); err != nil {
ll = 127 getty.GetLogger().Errorf("[closeVirtualConnection] error %d->%s", serialNumber, err.Error())
} }
majoraPacket.Extra = msg[:ll] }
}
if err := client.WriteAndFlush(packet); err != nil { func (client *Client) CloseAll(session getty.Session) {
logger.Error().Msgf("closeVirtualConnection with error %+v", err) defer func() {
if err := recover(); err != nil {
getty.GetLogger().Errorf("OnClose %+v", err)
} }
}()
client.connStore.Range(func(key, value interface{}) bool {
serialNumber := key.(int64)
conn, _ := value.(net.Conn)
getty.GetLogger().Infof("close serialNumber -> %d", serialNumber)
client.OnClose(session, conn, serialNumber)
return true
})
} }
package client
import (
"runtime"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common"
"virjar.com/majora-go/protocol"
)
type MajoraEventListener struct {
client *Client
}
func (m *MajoraEventListener) OnOpen(session getty.Session) error {
getty.GetLogger().Info("==================OnOpen==================")
packet := protocol.TypeRegister.CreatePacket()
packet.Extra = m.client.config.ClientID
extraMap := make(map[string]string, 1)
extraMap[common.ExtrakeyUser] = m.client.config.Extra.Account
packet.Data = protocol.EncodeExtra(extraMap)
if _, _, err := session.WritePkg(packet, time.Second*10); err != nil {
getty.GetLogger().Errorf("register to server error %+v", err)
return err
}
getty.GetLogger().Infof("[OnOpen] registe to %s success", m.client.config.TunnelAddr)
return nil
}
func (m *MajoraEventListener) OnClose(session getty.Session) {
getty.GetLogger().Infof("OnClose->%v,clean local session...", session.IsClosed())
m.client.CloseAll(session)
}
func (m *MajoraEventListener) OnError(session getty.Session, err error) {
getty.GetLogger().Errorf("OnError %s", err.Error())
m.client.CloseAll(session)
session.Close()
}
func (m *MajoraEventListener) OnCron(session getty.Session) {
getty.GetLogger().Debugf("thread:%d stat:%v", runtime.NumGoroutine(), session.IsClosed())
m.client.Redial(session)
}
func (m *MajoraEventListener) OnMessage(session getty.Session, input interface{}) {
majoraPacket := input.(*protocol.MajoraPacket)
getty.GetLogger().Infof("receive packet %d->%s", majoraPacket.SerialNumber, majoraPacket.Ttype.ToString())
switch majoraPacket.Ttype {
case protocol.TypeHeartbeat:
m.client.handleHeartbeat(session)
case protocol.TypeConnect:
m.client.handleConnect(majoraPacket, session)
case protocol.TypeTransfer:
m.client.handleTransfer(majoraPacket, session)
case protocol.TypeDisconnect:
m.client.handleDisconnectMessage(session, majoraPacket)
case protocol.TypeControl:
m.client.handleControlMessage(majoraPacket)
case protocol.TypeDestroy:
m.client.handleDestroyMessage()
}
}
package client
import (
"fmt"
"net"
"time"
"github.com/adamweixuan/getty"
gxsync "github.com/adamweixuan/gostnops/sync"
"virjar.com/majora-go/infra"
)
var (
taskPool = gxsync.NewTaskPoolSimple(10000)
)
func (client *Client) connect() {
hostPort := client.config.TunnelAddr
if len(hostPort) == 0 {
panic("invalid nat host/port info")
}
reConnect := client.config.ReconnInterval
gettyCli := getty.NewTCPClient(
getty.WithServerAddress(hostPort),
getty.WithConnectionNumber(1),
getty.WithReconnectInterval(int(reConnect.Milliseconds())),
getty.WithClientTaskPool(taskPool))
gettyCli.RunEventLoop(NewClientSession(client))
client.natTunnel = gettyCli
getty.GetLogger().Infof("connect to nathost %s success ...", hostPort)
}
func NewClientSession(client *Client) func(getty.Session) error {
return func(session getty.Session) error {
return InitialSession(session, client)
}
}
func InitialSession(session getty.Session, client *Client) (err error) {
tcpConn, ok := session.Conn().(*net.TCPConn)
if !ok {
panic(fmt.Sprintf("newSession: %s, session.conn{%#v} is not tcp connection", session.Stat(), session.Conn()))
}
if err = tcpConn.SetNoDelay(true); err != nil {
return err
}
if err = tcpConn.SetKeepAlive(true); err != nil {
return err
}
if err = tcpConn.SetKeepAlivePeriod(10 * time.Second); err != nil {
return err
}
if err = tcpConn.SetReadBuffer(262144); err != nil {
return err
}
if err = tcpConn.SetWriteBuffer(524288); err != nil {
return err
}
session.SetName("majora-cli")
//session.SetMaxMsgLen(128 * 1024) // max message package length is 128k
session.SetMaxMsgLen(8 * 1024) // max message package length is 128k
session.SetReadTimeout(time.Second * 10)
session.SetWriteTimeout(time.Second * 10)
session.SetWaitTime(time.Second * 10)
if client.config.Redial.Valid() {
getty.GetLogger().Infof("ReconnInterval %+v", client.config.Redial.RedialDuration)
session.SetCronPeriod(int(client.config.Redial.RedialDuration.Milliseconds()))
}
session.SetPkgHandler(PkgCodec)
session.SetEventListener(&MajoraEventListener{
client: client,
})
return nil
}
func (client *Client) Redial(session getty.Session) {
if !client.config.Redial.Valid() {
getty.GetLogger().Warnf("Redial invalid")
return
}
client.CloseAll(session)
if _, _, err := session.WritePkg(OfflinePacket, time.Second*10); err != nil {
getty.GetLogger().Warnf("write offline to server error %s", err.Error())
}
getty.GetLogger().Info("=================redial start ==============")
time.Sleep(client.config.Redial.WaitTime)
infra.Redial(client.config)
}
package client package client
import (
"virjar.com/majora-go/logger"
"virjar.com/majora-go/protocol"
)
const ( const (
ActionExecShell = "executeShell" ActionExecShell = "executeShell"
ActionRedial = "redial" ActionRedial = "redial"
...@@ -29,12 +24,12 @@ type CmdResponse struct { ...@@ -29,12 +24,12 @@ type CmdResponse struct {
} }
func (c *CmdResponse) OnCmdResponse(_ bool, response map[string]string) { func (c *CmdResponse) OnCmdResponse(_ bool, response map[string]string) {
packet := protocol.TypeControl.CreatePacket() //packet := protocol.TypeControl.CreatePacket()
packet.SerialNumber = c.SerialNumber //packet.SerialNumber = c.SerialNumber
packet.Data = protocol.EncodeExtra(response) //packet.Data = protocol.EncodeExtra(response)
if err := c.Client.WriteAndFlush(packet); err != nil { //if err := c.Client.WriteAndFlush(packet); err != nil {
logger.Error().Msgf("OnCmdResponse error %+v", err) // logger.Error().Msgf("OnCmdResponse error %+v", err)
} //}
} }
//func OnRedialCmdResponse(client *Client, serialNumber int64, success bool, response map[string]string) { //func OnRedialCmdResponse(client *Client, serialNumber int64, success bool, response map[string]string) {
......
...@@ -7,11 +7,13 @@ import ( ...@@ -7,11 +7,13 @@ import (
"io" "io"
"time" "time"
"virjar.com/majora-go/logger" "github.com/adamweixuan/getty"
) )
const ( const (
MagicSize = 8 MagicSize = 8
FrameSize = 4
HeaderSize = FrameSize + FrameSize
TypeSize = 1 TypeSize = 1
ExtraSize = 1 ExtraSize = 1
SerialNumberSize = 8 SerialNumberSize = 8
...@@ -116,7 +118,7 @@ func ReadN(size int, conn io.Reader) ([]byte, error) { ...@@ -116,7 +118,7 @@ func ReadN(size int, conn io.Reader) ([]byte, error) {
func ReadMagic(buf []byte) bool { func ReadMagic(buf []byte) bool {
magic := int64(binary.BigEndian.Uint64(buf)) magic := int64(binary.BigEndian.Uint64(buf))
if magic != MAGIC { if magic != MAGIC {
logger.Error().Msgf("magic not equal %d|%d|%+v", magic, MAGIC, buf) getty.GetLogger().Errorf("magic not equal %d|%d|%+v", magic, MAGIC, buf)
} }
return magic == MAGIC return magic == MAGIC
} }
tunnel_addr = 127.0.0.1:5879 tunnel_addr = 127.0.0.1:5879
;tunnel_addr = aoba.vip:5879
dns_server = 114.114.114.114:53 dns_server = 114.114.114.114:53
;bind to local ip ;bind to local ip
;local_ip = 192.168.0.100 ;local_ip = 192.168.0.100
...@@ -14,7 +15,11 @@ reconn_interval = 5s ...@@ -14,7 +15,11 @@ reconn_interval = 5s
account = superman account = superman
[redial] [redial]
; on windows is cmd.exe
; on *nix is /bin/bash
;command = /bin/bash ;command = /bin/bash
;exec_path = /root/ppp_auto_with_auth.sh ; windows bat 脚本的绝对路径
;redial_duration = 5m ; *nix shell脚本的绝对路径 D:\redial\redial.bat
;wait_time = 10s ;exec_path = ls
redial_duration = 30s
wait_time = 10s
...@@ -11,7 +11,7 @@ cd `dirname $0` ...@@ -11,7 +11,7 @@ cd `dirname $0`
script_dir=`pwd` script_dir=`pwd`
function getPid(){ function getPid(){
echo `ps -ef | grep "majora" | grep "majoro.ini" | grep -v "grep" | grep -v "startup.sh" | awk '{print $2}'` echo `ps -ef | grep "majora" | grep ".ini" | grep -v "grep" | grep -v "startup.sh" | awk '{print $2}'`
} }
remote_pid=`getPid` remote_pid=`getPid`
......
...@@ -3,10 +3,19 @@ module virjar.com/majora-go ...@@ -3,10 +3,19 @@ module virjar.com/majora-go
go 1.17 go 1.17
require ( require (
github.com/adamweixuan/getty v1.8.1
github.com/adamweixuan/gostnops v1.11.20-0.20211029124314-3f0589fceea6
github.com/blang/semver/v4 v4.0.0 github.com/blang/semver/v4 v4.0.0
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/rs/zerolog v1.25.0 github.com/rs/zerolog v1.25.0
gopkg.in/ini.v1 v1.63.2 gopkg.in/ini.v1 v1.63.2
) )
require github.com/stretchr/testify v1.7.0 // indirect require (
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.19.1 // indirect
)
github.com/adamweixuan/getty v1.8.0 h1:rF0dHYJvnKj82wmtjRetpFoUUwO2VlezNqWiocqerXs=
github.com/adamweixuan/getty v1.8.0/go.mod h1:JFfNdX0dvMtvPiF7LEfU4X8OLJYao5BGTHS9cf4kng8=
github.com/adamweixuan/getty v1.8.1 h1:UaGN4WMkwATHrYG4xSAut0zvRzfssOgekpWx1kBsWQY=
github.com/adamweixuan/getty v1.8.1/go.mod h1:JFfNdX0dvMtvPiF7LEfU4X8OLJYao5BGTHS9cf4kng8=
github.com/adamweixuan/gostnops v1.11.20-0.20211029124314-3f0589fceea6 h1:UGMsACjkGfNRKCz5U8ijtkpKL8o/25rGHxTV1adWjak=
github.com/adamweixuan/gostnops v1.11.20-0.20211029124314-3f0589fceea6/go.mod h1:zZYjPhU2+ujyEOWWE0l1pEdf5H4CyfiMG//rSpNjwcQ=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
...@@ -13,12 +31,25 @@ github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= ...@@ -13,12 +31,25 @@ github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II=
github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
...@@ -33,13 +64,18 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn ...@@ -33,13 +64,18 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
...@@ -2,52 +2,39 @@ package infra ...@@ -2,52 +2,39 @@ package infra
import ( import (
"os/exec" "os/exec"
"runtime"
"virjar.com/majora-go/logger" "github.com/adamweixuan/getty"
"virjar.com/majora-go/model" "virjar.com/majora-go/model"
) )
//func Redial(cfg *model.Configure, cleanup chan struct{}) { const (
//redial(cfg) cmdWin = "/C"
//RestartBySignal(cleanup) cmdUnix = "-c"
//} )
//func redial(cfg *model.Configure) {
// execPath := cfg.Redial.ExecPath
// if len(execPath) == 0 {
// logger.Error().Msgf("redial exec file is empty")
// return
// }
// command := cfg.Redial.Command
// if len(command) == 0 {
// logger.Error().Msgf("redial command is empty")
// return
// }
// cmd := exec.Command(command, "-c", execPath)
// output, err := cmd.Output()
// if err != nil {
// logger.Error().Msgf("Execute Shell:%s failed with error:%s", command, err.Error())
// return
// }
// logger.Info().Msgf("[redial] redial success %+v resp:%s", cmd, string(output))
//}
func Redial(cfg *model.Configure) { func Redial(cfg *model.Configure) {
execPath := cfg.Redial.ExecPath execPath := cfg.Redial.ExecPath
if len(execPath) == 0 { if len(execPath) == 0 {
logger.Error().Msgf("redial exec file is empty") getty.GetLogger().Warn("redial exec file is empty")
return return
} }
command := cfg.Redial.Command command := cfg.Redial.Command
if len(command) == 0 { if len(command) == 0 {
logger.Error().Msgf("redial command is empty") getty.GetLogger().Warn("redial command is empty")
return return
} }
cmd := exec.Command(command, "-c", execPath)
args := cmdUnix
if runtime.GOOS == "windows" {
args = cmdWin
}
cmd := exec.Command(command, args, execPath)
output, err := cmd.Output() output, err := cmd.Output()
if err != nil { if err != nil {
logger.Error().Msgf("Execute Shell:%s failed with error:%s", command, err.Error()) getty.GetLogger().Errorf("Execute Shell:%s failed with error:%s", command, err.Error())
return return
} }
logger.Info().Msgf("[redial] redial success %+v resp:%s", cmd, string(output)) getty.GetLogger().Infof("[redial] redial success %+v resp:%s", cmd, string(output))
} }
...@@ -10,9 +10,9 @@ import ( ...@@ -10,9 +10,9 @@ import (
"runtime" "runtime"
"strings" "strings"
"github.com/adamweixuan/getty"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"virjar.com/majora-go/common" "virjar.com/majora-go/common"
"virjar.com/majora-go/logger"
) )
// getBinary 下载二进制 // getBinary 下载二进制
...@@ -22,8 +22,7 @@ func getBinary(name, os, arch, version string) (io.ReadCloser, error) { ...@@ -22,8 +22,7 @@ func getBinary(name, os, arch, version string) (io.ReadCloser, error) {
fileName += ".exe" fileName += ".exe"
} }
url := common.UpdateServer + common.UpdateBinaryPath + fileName url := common.UpdateServer + common.UpdateBinaryPath + fileName
getty.GetLogger().Debugf("getBinary url %s, filename %s", url, fileName)
logger.Debug().Msgf("getBinary url %s, filename %s", url, fileName)
body, err := http.DefaultClient.Get(url) body, err := http.DefaultClient.Get(url)
if err != nil { if err != nil {
...@@ -67,24 +66,24 @@ func rename(src, dst string) error { ...@@ -67,24 +66,24 @@ func rename(src, dst string) error {
if err := os.Rename(src, dst); err != nil { if err := os.Rename(src, dst); err != nil {
return err return err
} }
logger.Debug().Msgf("rename %s to %s", src, dst) getty.GetLogger().Debugf("rename %s to %s", src, dst)
return nil return nil
} }
func UpdateCore(name, latestVer, targetFile string) (bool, error) { func UpdateCore(name, latestVer, targetFile string) (bool, error) {
tf, err := ioutil.TempFile("", "") tf, err := ioutil.TempFile("", "")
if err != nil { if err != nil {
logger.Debug().Msgf("UpdateCore TempFile with error %s", err.Error()) getty.GetLogger().Debugf("UpdateCore TempFile with error %s", err.Error())
return false, err return false, err
} }
if err := downloadFile(name, runtime.GOOS, runtime.GOARCH, latestVer, tf); err != nil { if err := downloadFile(name, runtime.GOOS, runtime.GOARCH, latestVer, tf); err != nil {
logger.Debug().Msgf("UpdateCore downloadFile with error %s", err.Error()) getty.GetLogger().Debugf("UpdateCore downloadFile with error %s", err.Error())
return false, err return false, err
} }
if err := tf.Close(); err != nil { if err := tf.Close(); err != nil {
logger.Debug().Msgf("UpdateCore tf close with error %s", err.Error()) getty.GetLogger().Debugf("UpdateCore tf close with error %s", err.Error())
return false, err return false, err
} }
...@@ -97,7 +96,7 @@ func UpdateCore(name, latestVer, targetFile string) (bool, error) { ...@@ -97,7 +96,7 @@ func UpdateCore(name, latestVer, targetFile string) (bool, error) {
func getLatestVersion() (string, error) { func getLatestVersion() (string, error) {
url := common.UpdateServer + common.UpdateBinaryPath + common.Latest url := common.UpdateServer + common.UpdateBinaryPath + common.Latest
logger.Debug().Msgf("getLatestVersion from %s", url) getty.GetLogger().Debugf("getLatestVersion from %s", url)
resp, err := http.DefaultClient.Get(url) //nolint:bodyclose resp, err := http.DefaultClient.Get(url) //nolint:bodyclose
if err != nil || resp == nil { if err != nil || resp == nil {
return "", err return "", err
...@@ -108,7 +107,7 @@ func getLatestVersion() (string, error) { ...@@ -108,7 +107,7 @@ func getLatestVersion() (string, error) {
}(resp.Body) }(resp.Body)
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
logger.Error().Msgf("get latest version with error %s->%d", url, resp.StatusCode) getty.GetLogger().Errorf("get latest version with error %s->%d", url, resp.StatusCode)
return "", nil return "", nil
} }
...@@ -126,12 +125,12 @@ func needUpdate(curVer string) (bool, string) { ...@@ -126,12 +125,12 @@ func needUpdate(curVer string) (bool, string) {
} }
latestVer, err := getLatestVersion() latestVer, err := getLatestVersion()
if err != nil { if err != nil {
logger.Error().Msgf("getLatestVersion with error %s", err.Error()) getty.GetLogger().Errorf("getLatestVersion with error %s", err.Error())
return false, "" return false, ""
} }
if len(latestVer) == 0 { if len(latestVer) == 0 {
logger.Error().Msgf("getLatestVersion with empty") getty.GetLogger().Errorf("getLatestVersion with empty")
return false, "" return false, ""
} }
...@@ -145,7 +144,7 @@ func needUpdate(curVer string) (bool, string) { ...@@ -145,7 +144,7 @@ func needUpdate(curVer string) (bool, string) {
} }
cur, _ := semver.Make(curVer) cur, _ := semver.Make(curVer)
next, _ := semver.Make(latest) next, _ := semver.Make(latest)
logger.Debug().Msgf("curVer %s->cur %s, latestVer %s->next %s", curVer, cur, latest, next) getty.GetLogger().Debugf("curVer %s->cur %s, latestVer %s->next %s", curVer, cur, latest, next)
return cur.Compare(next) < 0, latestVer return cur.Compare(next) < 0, latestVer
} }
...@@ -154,7 +153,7 @@ func needUpdate(curVer string) (bool, string) { ...@@ -154,7 +153,7 @@ func needUpdate(curVer string) (bool, string) {
func Update(name, curVer string) (bool, error) { func Update(name, curVer string) (bool, error) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
logger.Error().Msgf("Update with error %+v", err) getty.GetLogger().Errorf("Update with error %+v", err)
} }
}() }()
...@@ -164,21 +163,20 @@ func Update(name, curVer string) (bool, error) { ...@@ -164,21 +163,20 @@ func Update(name, curVer string) (bool, error) {
return false, err return false, err
} }
logger.Debug().Msgf("current exec info %s", executable) getty.GetLogger().Debugf("current exec info %s", executable)
// check has new version // check has new version
needUpdate, latestVer := needUpdate(curVer) needUpdate, latestVer := needUpdate(curVer)
logger.Debug().Msgf("curVer %s, latestVer %s, need update %v", curVer, latestVer, needUpdate) getty.GetLogger().Debugf("curVer %s, latestVer %s, need update %v", curVer, latestVer, needUpdate)
if !needUpdate { if !needUpdate {
logger.Debug().Msgf("no need update ...") getty.GetLogger().Debugf("no need update ...")
return false, nil return false, nil
} }
updateStatus, err := UpdateCore(name, latestVer, executable) updateStatus, err := UpdateCore(name, latestVer, executable)
if err != nil { if err != nil {
logger.Error().Msgf("update to latest version with error %s", err) getty.GetLogger().Errorf("update to latest version with error %s", err)
return false, err return false, err
} }
getty.GetLogger().Infof("update from %s to %s with success %v", curVer, latestVer, updateStatus)
logger.Info().Msgf("update from %s to %s with success %v", curVer, latestVer, updateStatus)
return updateStatus, nil return updateStatus, nil
} }
...@@ -64,7 +64,7 @@ func InitConf(path string) *Configure { ...@@ -64,7 +64,7 @@ func InitConf(path string) *Configure {
return conf return conf
} }
func (r Redial) Invalid() bool { func (r Redial) Valid() bool {
if len(r.Command) == 0 { if len(r.Command) == 0 {
return false return false
} }
...@@ -73,7 +73,7 @@ func (r Redial) Invalid() bool { ...@@ -73,7 +73,7 @@ func (r Redial) Invalid() bool {
return false return false
} }
if r.RedialDuration == 0 { if r.RedialDuration <= 0 {
return false return false
} }
return true return true
......
...@@ -47,12 +47,12 @@ for os in $os_all; do ...@@ -47,12 +47,12 @@ for os in $os_all; do
cd ./packages cd ./packages
if [ "x${os}" = x"windows" ]; then if [ "x${os}" = x"windows" ]; then
zip -rq ${majora_dir_name}.zip ${majora_dir_name} zip -rq ${majora_dir_name}.zip ${majora_dir_name}
curl -F file=@"${majora_dir_name}.zip" -F token=$TOKEN http://81.70.224.147:10010/version/"$majora_version" # curl -F file=@"${majora_dir_name}.zip" -F token=$TOKEN http://81.70.224.147:10010/version/"$majora_version"
curl -F file=@"${majora_dir_name}.zip" -F token=$TOKENONLINE https://oss.virjar.com/majora/bin/"$majora_version" # curl -F file=@"${majora_dir_name}.zip" -F token=$TOKENONLINE https://oss.virjar.com/majora/bin/"$majora_version"
else else
tar -zcf ${majora_dir_name}.tar.gz ${majora_dir_name} tar -zcf ${majora_dir_name}.tar.gz ${majora_dir_name}
curl -F file=@"${majora_dir_name}.tar.gz" -F token=$TOKEN http://81.70.224.147:10010/version/"$majora_version" # curl -F file=@"${majora_dir_name}.tar.gz" -F token=$TOKEN http://81.70.224.147:10010/version/"$majora_version"
curl -F file=@"${majora_dir_name}.tar.gz" -F token=$TOKENONLINE https://oss.virjar.com/majora/bin/"$majora_version" # curl -F file=@"${majora_dir_name}.tar.gz" -F token=$TOKENONLINE https://oss.virjar.com/majora/bin/"$majora_version"
fi fi
cd .. cd ..
rm -rf ${majora_path} rm -rf ${majora_path}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment