Commit 7aeb66e2 authored by wei.xuan's avatar wei.xuan

1112

parent 76aca1d4
......@@ -10,3 +10,4 @@ release
*.log
majora.log
std.log
majora
\ No newline at end of file
......@@ -6,8 +6,9 @@ DATE=$(shell date +"%Y-%m-%d")
BUILDINFO := -X main.Version=latest -X main.Date=$(DATE)
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 majora
clean:
rm -fr majora-go
rm -fr majora
rm -fr output
\ No newline at end of file
......@@ -5,21 +5,20 @@ import (
"encoding/json"
"flag"
"fmt"
"log"
"math/rand"
"net"
"net/http"
_ "net/http/pprof"
"os"
"os/exec"
"os/signal"
"runtime"
"runtime/debug"
"syscall"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/client"
"virjar.com/majora-go/common"
"virjar.com/majora-go/log"
"virjar.com/majora-go/model"
)
......@@ -31,7 +30,7 @@ var (
account string
dnsServer string
localAddr string
disableUpdate bool
daemon bool
)
var (
......@@ -39,6 +38,10 @@ var (
Date string
)
var (
cmd *exec.Cmd
)
func init() {
rand.Seed(time.Now().UnixNano())
flag.StringVar(&configure, "conf", "", "./majora -c path/to/your/majora.ini")
......@@ -48,21 +51,18 @@ func init() {
flag.StringVar(&account, "account", "unknown", "account")
flag.StringVar(&dnsServer, "dnsServer", common.DNSServer, "custom dns server")
flag.StringVar(&localAddr, "localIp", "", "bind local ip")
flag.BoolVar(&disableUpdate, "disableUpdate", false, "disable self update")
flag.BoolVar(&daemon, "daemon", false, "daemon")
flag.Parse()
}
func initial(cfg *model.Configure) {
if cfg.LogLevel > 0 {
_ = getty.SetLoggerLevel(getty.LoggerLevel(cfg.LogLevel - 1))
_ = getty.Online(cfg.LogPath)
}
log.Init(cfg.LogLevel - 1)
if cfg.PprofPort > 0 {
go func() {
addr := fmt.Sprintf("127.0.0.1:%d", cfg.PprofPort)
getty.GetLogger().Infof("enable pprof: %s", addr)
log.Fatal(http.ListenAndServe(addr, nil))
log.Run().Infof("enable pprof: %s", addr)
log.Run().Error(http.ListenAndServe(addr, nil))
}()
}
......@@ -73,7 +73,6 @@ func initial(cfg *model.Configure) {
return net.Dial("udp", dnsServer)
},
}
getty.GetLogger().Infof("use custom dns server %s", dnsServer)
}
}
......@@ -82,28 +81,36 @@ func parseFromCmd(cfg *model.Configure) {
cfg.LogLevel = logLevel
cfg.DNSServer = dnsServer
cfg.LocalAddr = localAddr
cfg.DisableUpdate = disableUpdate
// 先兼容吧
cfg.Extra.Account = account
cfg.PprofPort = pprofPort
}
func cli() {
func cli(cfg *model.Configure) {
defer func() {
if err := recover(); err != nil {
log.Run().Errorf("cli panic %+v", err)
}
}()
log.Run().Infof("cpu count %d proc %d", runtime.NumCPU(), runtime.NumCPU()*2)
log.Run().Infof("current Version %s, build at %s", Version, Date)
log.Run().Infof("hostinfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH)
cfgInfo, _ := json.Marshal(cfg)
log.Run().Infof("config info:%s", string(cfgInfo))
client.NewClientWithConf(cfg)
}
func initConf() *model.Configure {
cfg := model.NewDefMajoraConf()
if len(configure) > 0 {
cfg = model.InitConf(configure)
} else {
parseFromCmd(cfg)
}
//runtime.GOMAXPROCS(runtime.NumCPU() * 2)
//debug.SetGCPercent(200)
initial(cfg)
runtime.GOMAXPROCS(runtime.NumCPU() * 2)
debug.SetGCPercent(200)
getty.GetLogger().Warnf("cpu count %d proc %d", runtime.NumCPU(), runtime.NumCPU()*2)
getty.GetLogger().Warnf("current Version %s, build at %s", Version, Date)
getty.GetLogger().Warnf("hostinfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH)
cfgInfo, _ := json.Marshal(cfg)
getty.GetLogger().Warnf("config info:%s", string(cfgInfo))
client.NewClientWithConf(cfg)
return cfg
}
//main start
......@@ -112,15 +119,29 @@ func main() {
fmt.Println(Version)
os.Exit(0)
}
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
cfg := initConf()
if daemon {
var args []string
for _, arg := range os.Args[1:] {
if arg != "-daemon" {
args = append(args, arg)
}
}
cmd = exec.Command(os.Args[0], args...)
cmd.Env = os.Environ()
if err := cmd.Start(); err != nil {
panic(err)
}
log.Run().Infof("%s [pid-%d] running...\n", os.Args[0], cmd.Process.Pid)
os.Exit(0)
}
go func() {
cli()
}()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
cli(cfg)
select {
case <-sigs:
case <-signalChan:
time.Sleep(time.Second * 3)
getty.GetLogger().Warn("main process exit...")
log.Run().Warn("main process exit...")
}
}
......@@ -3,8 +3,11 @@ package client
import (
"net"
"sync"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/infra"
"virjar.com/majora-go/log"
"virjar.com/majora-go/model"
)
......@@ -17,8 +20,7 @@ type Client struct {
}
func NewClientWithConf(cfg *model.Configure) {
client := NewCli(cfg)
client.StartUp()
NewCli(cfg).StartUp()
}
func NewCli(cfg *model.Configure) *Client {
......@@ -39,5 +41,38 @@ func NewCli(cfg *model.Configure) *Client {
}
func (client *Client) StartUp() {
client.check()
client.connect()
}
func (client *Client) check() {
cfg := client.config
if !cfg.Redial.Valid() {
return
}
interval := cfg.NetCheckInterval
if interval <= 0 {
interval = time.Second * 5
}
url := infra.RandUrl()
if len(cfg.NetCheckUrl) > 0 {
url = cfg.NetCheckUrl
}
go func() {
var timer = time.NewTimer(interval)
for {
timer.Reset(interval)
<-timer.C
success := infra.Ping(url)
if success {
continue
}
log.Run().Warnf("net check fail, redial...")
infra.RedialByCheck(cfg)
}
}()
}
......@@ -6,6 +6,7 @@ import (
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common"
"virjar.com/majora-go/log"
"virjar.com/majora-go/protocol"
)
......@@ -17,16 +18,16 @@ 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))
log.Run().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]))
log.Run().Debugf("[PacketCodec] read magic %+v", binary.BigEndian.Uint64(data[0:8]))
readmagic := data[0:common.MagicSize]
if !common.ReadMagic(readmagic) {
getty.GetLogger().Errorf("[PacketCodec] invalid magic %d|%s",
log.Run().Errorf("[PacketCodec] invalid magic %d|%s",
binary.BigEndian.Uint64(readmagic), string(readmagic))
return nil, 0, common.ErrInvalidMagic
}
......@@ -35,26 +36,26 @@ func (p *PacketCodec) Read(session getty.Session, data []byte) (interface{}, int
frameLen, err := common.ReadInt32(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] frameLen error %+v", err)
log.Run().Errorf("[PacketCodec] frameLen error %+v", err)
return nil, 0, err
}
// 缓冲区数据不够
if reader.Len() < int(frameLen) {
getty.GetLogger().Errorf("[PacketCodec] buf not enough %d|%d", reader.Len(), frameLen)
log.Run().Debugf("[PacketCodec] buf not enough %d|%d", reader.Len(), frameLen)
return nil, 0, nil
}
getty.GetLogger().Debugf("[PacketCodec] read frameLen %d", frameLen)
log.Run().Debugf("[PacketCodec] read frameLen %d", frameLen)
// type
msgType, err := common.ReadByte(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read type error %+v", err)
log.Run().Errorf("[PacketCodec] read type error %+v", err)
return nil, 0, err
}
getty.GetLogger().Debugf("[PacketCodec] read msgType %+v", msgType)
log.Run().Debugf("[PacketCodec] read msgType %+v", msgType)
pack := &protocol.MajoraPacket{}
pack.Ttype = protocol.MajoraPacketType(msgType)
......@@ -62,43 +63,43 @@ func (p *PacketCodec) Read(session getty.Session, data []byte) (interface{}, int
// num
pack.SerialNumber, err = common.ReadInt64(reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read num error %+v", err)
log.Run().Errorf("[PacketCodec] read num error %+v", err)
return nil, len(data), nil
}
getty.GetLogger().Debugf("[PacketCodec] read SerialNumber %d", pack.SerialNumber)
log.Run().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)
log.Run().Errorf("[PacketCodec] read extra size error %+v", err)
return nil, len(data), nil
}
extra, err := common.ReadN(int(extraSize), reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read extra error %+v", err)
log.Run().Errorf("[PacketCodec] read extra error %+v", err)
return nil, len(data), nil
}
pack.Extra = string(extra)
getty.GetLogger().Debugf("[PacketCodec] read extra %s", pack.Extra)
log.Run().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)
log.Run().Errorf("[PacketCodec] read frameLen error %+v", err)
return nil, len(data), common.ErrInvalidSize
}
if dataSize > 0 {
data, err := common.ReadN(dataSize, reader)
if err != nil {
getty.GetLogger().Errorf("[PacketCodec] read data error %+v", err)
log.Run().Errorf("[PacketCodec] read data error %+v", err)
return nil, len(data), nil
}
pack.Data = data
}
getty.GetLogger().Debugf("[PacketCodec] read response %d", int(frameLen+12))
log.Run().Debugf("[PacketCodec] read response %d", int(frameLen+12))
return pack, int(frameLen + 12), nil
}
......
This diff is collapsed.
......@@ -6,6 +6,7 @@ import (
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common"
"virjar.com/majora-go/log"
"virjar.com/majora-go/protocol"
)
......@@ -20,32 +21,31 @@ func (m *MajoraEventListener) OnOpen(session getty.Session) error {
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)
log.Event().Errorf("register to server error %+v", err)
return err
}
getty.GetLogger().Warnf("[OnOpen] registe to %s success", m.client.config.TunnelAddr)
log.Event().Infof("[OnOpen] registe to %s success", m.client.config.TunnelAddr)
return nil
}
func (m *MajoraEventListener) OnClose(session getty.Session) {
getty.GetLogger().Errorf("OnClose->%v,clean local session...", session.IsClosed())
log.Event().Errorf("OnClose-> session closed %v", session.IsClosed())
m.client.CloseAll(session)
}
func (m *MajoraEventListener) OnError(session getty.Session, err error) {
getty.GetLogger().Errorf("OnError %s", err.Error())
log.Event().Errorf("OnError %s", err.Error())
m.client.CloseAll(session)
}
func (m *MajoraEventListener) OnCron(session getty.Session) {
getty.GetLogger().Warnf("thread:%d stat:%v", runtime.NumGoroutine(), session.IsClosed())
log.Event().Warnf("thread:%d session closed %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 from server %d->%s,extra:%s", majoraPacket.SerialNumber,
majoraPacket.Ttype.ToString(), majoraPacket.Extra)
log.Event().Debugf("receive packet from server %d->%s", majoraPacket.SerialNumber, majoraPacket.Ttype.ToString())
switch majoraPacket.Ttype {
case protocol.TypeHeartbeat:
......
......@@ -7,14 +7,14 @@ import (
"time"
"github.com/adamweixuan/getty"
gxsync "github.com/adamweixuan/gostnops/sync"
"virjar.com/majora-go/common"
"virjar.com/majora-go/infra"
"virjar.com/majora-go/log"
)
var (
taskPool = gxsync.NewTaskPoolSimple(5000)
)
//var (
//taskPool = gxsync.NewTaskPoolSimple(5000)
//)
func (client *Client) connect() {
hostPort := client.config.TunnelAddr
......@@ -27,9 +27,9 @@ func (client *Client) connect() {
gettyCli := getty.NewTCPClient(
getty.WithServerAddress(hostPort),
getty.WithConnectionNumber(1),
//getty.WithClientTaskPool(taskPool),
getty.WithReconnectInterval(int(reConnect.Milliseconds())),
getty.WithLocalAddressClient(client.localAddr),
getty.WithClientTaskPool(taskPool))
getty.WithLocalAddressClient(client.localAddr))
gettyCli.RunEventLoop(NewClientSession(client))
client.natTunnel = gettyCli
}
......@@ -43,7 +43,7 @@ func NewClientSession(client *Client) func(getty.Session) error {
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()))
panic(fmt.Sprintf("invalid session %+v", session.Conn()))
}
if err = tcpConn.SetNoDelay(true); err != nil {
......@@ -63,7 +63,7 @@ func InitialSession(session getty.Session, client *Client) (err error) {
}
session.SetName(common.SessionName)
session.SetMaxMsgLen(common.KB8) // max message package length is 128k
session.SetMaxMsgLen(common.KB8)
session.SetReadTimeout(common.ReadTimeout)
session.SetWriteTimeout(common.WriteTimeout)
session.SetWaitTime(common.WaitTimeout)
......@@ -73,7 +73,7 @@ func InitialSession(session getty.Session, client *Client) (err error) {
// 加上随机 防止vps在同时间重启
randDuration := rand.Int63n(time.Minute.Milliseconds() * 5)
interval := randDuration + client.config.Redial.RedialDuration.Milliseconds()
getty.GetLogger().Infof("ReconnInterval %+v", interval)
log.Run().Infof("redial interval %+v", time.Duration(interval)*time.Millisecond)
session.SetCronPeriod(int(interval))
}
session.SetPkgHandler(PkgCodec)
......@@ -84,17 +84,16 @@ func InitialSession(session getty.Session, client *Client) (err error) {
}
func (client *Client) Redial(session getty.Session) {
getty.GetLogger().Warnf("=================redial start %v ==============", client.config.Redial.Valid())
log.Run().Infof("redial start ...%v", client.config.Redial.Valid())
if !client.config.Redial.Valid() {
return
}
getty.GetLogger().Warn("=================redial->offline ==============")
if _, _, err := session.WritePkg(OfflinePacket, time.Second*10); err != nil {
getty.GetLogger().Warnf("write offline to server error %s", err.Error())
log.Run().Warn("redial send offline message ...")
if _, _, err := session.WritePkg(OfflinePacket, 0); err != nil {
log.Run().Warnf("write offline to server error %s", err.Error())
}
getty.GetLogger().Warn("=================redial->close local session ==============")
log.Run().Warn("redial close local session")
client.CloseAll(session)
getty.GetLogger().Warnf("=================redial->wait %v ==============", client.config.Redial.WaitTime)
time.Sleep(client.config.Redial.WaitTime)
infra.Redial(client.config, session)
}
......@@ -4,7 +4,7 @@ import (
"os/exec"
"strings"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
)
var (
......@@ -30,7 +30,7 @@ func (e *ShellCmd) Handle(param map[string]string, callback Callback) {
callback.OnCmdResponse(false, cmdErrorMap)
return
}
getty.GetLogger().Infof("exec cmd %s", targetCmd)
log.Run().Infof("exec cmd %s", targetCmd)
trueCmd := strings.Split(targetCmd, " ")
......@@ -38,7 +38,7 @@ func (e *ShellCmd) Handle(param map[string]string, callback Callback) {
out, err := cmd.CombinedOutput()
if err != nil {
getty.GetLogger().Errorf("exec error %+v", err)
log.Run().Errorf("exec error %+v", err)
return
}
......
......@@ -51,6 +51,7 @@ const (
KeepAliveTimeout = time.Second * 10
SessionTimeout = time.Minute * 5
HeartBeatTimeout = time.Second * 30
UpstreamTimeout = time.Minute
)
......
......@@ -5,12 +5,10 @@ dns_server = 114.114.114.114:53
;local_ip = 192.168.0.100
;for performance pprof 0 is close
pprof_port = 16666
disable_update = false
; default is info
log_level = 1
reconn_interval = 5s
;client_id =
log_path = "./majora.log"
net_check_interval = 5s
net_check_url = https://www.baidu.com
[extra]
account = superman
......@@ -22,5 +20,5 @@ account = superman
; windows bat 脚本的绝对路径
; *nix shell脚本的绝对路径 D:\redial\redial.bat
;exec_path = ls
redial_duration = 30s
wait_time = 10s
;redial_duration = 30s
;wait_time = 10s
tunnel_addr = majora-dev.virjar.com:5879
tunnel_addr = majora-vps-zj.virjar.com:5879
dns_server = 114.114.114.114:53
;bind to local ip
;local_ip = 192.168.0.100
;for performance pprof 0 is close
;pprof_port = 0
disable_update = false
; default is info
log_level = 2
log_level = 1
reconn_interval = 5s
;client_id =
log_path = /root/majora.log
net_check_interval = 5s
net_check_url = https://www.baidu.com
[extra]
account = superman
[redial]
command = /bin/bash
exec_path = /root/ppp_auto_with_auth.sh
redial_duration = 10m
wait_time = 10s
;command = /bin/bash
;exec_path = /root/ppp_redial.sh
;redial_duration = 10m
;wait_time = 10s
[Unit]
Description=majora client
After=network.target
[Service]
Type=simple
User=root
Restart=always
RestartSec=5s
ExecStart=/root/majora -conf /root/majora.ini
ExecReload=/root/majora -conf /root/majora.ini
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
\ No newline at end of file
#!/usr/bin/env bash
rm -fr /usr/lib/systemd/system/majora.service
# create link
ln -s /root/majora.service /usr/lib/systemd/system/majora.service
sudo rm -fr /usr/lib/systemd/system/majora.service
sudo systemctl daemon-reload
sudo systemctl stop majora.service
systemctl daemon-reload
old_pid=$(ps -ef | grep majora | grep -v grep | awk '{print $2}')
echo "restart..."
echo "old pid is ${old_pid}"
systemctl restart majora.service
echo "clean old ..."
systemctl status majora.service
`ps -ef | grep majora | grep -v grep | awk '{print $2}'| xargs kill -9`
mkdir -p output/log
exec ./majora -daemon -conf majora.ini
\ No newline at end of file
......@@ -2,8 +2,6 @@
wget https://oss.virjar.com/majora/bin/latest/majora-cli_latest_linux_amd64.tar.gz -O majora-cli.tar.gz
tar -zxvf majora-cli.tar.gz
rm -fr majora
rm -fr exec.sh
rm -fr start.sh
......@@ -11,21 +9,11 @@ rm -fr majora.ini
rm -fr majora.service
rm -fr majora-dev.ini
rm -fr majora.log
rm -fr output
rm -fr std.log
mv -f majora-cli*/* .
rm -fr /usr/lib/systemd/system/majora.service
# create link
ln -s /root/majora.service /usr/lib/systemd/system/majora.service
systemctl daemon-reload
echo "start on reboot ..."
systemctl enable majora.service
tar -zxvf majora-cli.tar.gz
echo "restart..."
systemctl restart majora.service
mv -f majora-cli*/* .
systemctl status majora.service
exec bash ./start.sh
......@@ -3,8 +3,8 @@ module virjar.com/majora-go
go 1.17
require (
github.com/adamweixuan/getty v1.8.4
github.com/adamweixuan/gostnops v1.11.20-0.20211029124314-3f0589fceea6
github.com/adamweixuan/getty v0.0.1
github.com/adamweixuan/gostnops v0.0.1
github.com/google/uuid v1.3.0
gopkg.in/ini.v1 v1.63.2
)
......
github.com/adamweixuan/getty v1.8.4 h1:YhHVYwrSqky3cMrPV5/dfHUwrhc9XB7emobVXTe1wY4=
github.com/adamweixuan/getty v1.8.4/go.mod h1:+P0Afn1ky1/4q96pjJmR6GssmVYXN+2dZ/0BxkIDpGo=
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/adamweixuan/getty v0.0.1 h1:ze1++8zi9yF7QJnp9p1pbCn/7n5Ex5xrJKlFzpOu5q8=
github.com/adamweixuan/getty v0.0.1/go.mod h1:SnxNiA40Am3aSxaDnAYBBbd7iz9BtKUign8x1jNh2TU=
github.com/adamweixuan/gostnops v0.0.1 h1:oBfrRgBoRyaGjBTfq0DGH07jARS4OqN7jbSv1Mn05Fg=
github.com/adamweixuan/gostnops v0.0.1/go.mod h1:lTe81VUWCpja0NOVqXyi2cH28m2hYezzhTt3MudpDbU=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
......
......@@ -2,10 +2,11 @@ package infra
import (
"crypto/tls"
"math/rand"
"net/http"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
)
// 网络检测
......@@ -14,13 +15,23 @@ var (
httpcli *http.Client
)
var (
pingUrl = []string{
"https://www.baidu.com",
"https://www.bilibili.com",
"https://www.taobao.com",
"https://www.xiaohongshu.com",
"https://www.bytedance.com",
"https://pvp.qq.com",
}
)
const (
defTimeout = time.Second * 5
baiduUrl = "https://www.baidu.com"
)
func init() {
rand.Seed(time.Now().UnixNano())
httpcli = &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: defTimeout,
......@@ -35,14 +46,18 @@ func init() {
func Ping(url string) bool {
resp, err := httpcli.Head(url)
if err != nil {
getty.GetLogger().Warnf("ping %s with error %+v", url, err)
log.Run().Warnf("ping %s with error %+v", url, err)
return false
}
defer resp.Body.Close()
getty.GetLogger().Warnf("ping %s status code %d", url, resp.StatusCode)
return resp.StatusCode == http.StatusOK
return resp.StatusCode > 0
}
func RandomPing() bool {
return Ping(RandUrl())
}
func PingBaidu() bool {
return Ping(baiduUrl)
func RandUrl() string {
rand.Seed(time.Now().UnixNano())
return pingUrl[rand.Intn(len(pingUrl))]
}
......@@ -3,7 +3,7 @@ package infra
import (
"net"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
)
const (
......@@ -18,19 +18,19 @@ func GetIpByName(netname string) string {
ni, err := net.InterfaceByName(netname)
if err != nil {
getty.GetLogger().Warnf("get %s ip error %s", netname, err)
log.Run().Warnf("get %s ip error %s", netname, err)
return ""
}
addrs, err := ni.Addrs()
if err != nil {
getty.GetLogger().Warnf("get ip addr err %s", err)
log.Run().Warnf("get ip addr err %s", err)
return ""
}
if len(addrs) == 0 {
getty.GetLogger().Warnf("get ip addr empty ")
log.Run().Warnf("get ip addr empty ")
return ""
}
......@@ -43,7 +43,7 @@ func GetIpByName(netname string) string {
}
if ipv4Addr == nil {
getty.GetLogger().Warnf("interface %s don't have an ipv4 address", netname)
log.Run().Warnf("interface %s don't have an ipv4 address", netname)
return ""
}
return ipv4Addr.String()
......
......@@ -5,19 +5,19 @@ import (
"os/exec"
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
)
func Restart() {
cmd := exec.Command(os.Args[0], os.Args[1:]...) //nolint:gosec
cmd := exec.Command(os.Args[0], os.Args[1:]...)
cmd.Env = os.Environ()
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
getty.GetLogger().Debugf("Restart ... %+v", cmd)
log.Run().Debugf("Restart ... %+v", cmd)
if err := cmd.Run(); err != nil {
getty.GetLogger().Errorf("Restart error %+v", err)
log.Run().Errorf("Restart error %+v", err)
}
}
......@@ -25,7 +25,6 @@ func Restart() {
func RestartBySignal(signal chan struct{}) {
go func() {
time.Sleep(time.Second * 5)
getty.GetLogger().Infof("=============cleanup==============")
signal <- struct{}{}
}()
......@@ -34,8 +33,8 @@ func RestartBySignal(signal chan struct{}) {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
getty.GetLogger().Infof("[RestartBySignal] ... %+v", cmd)
log.Run().Infof("[RestartBySignal] ... %+v", cmd)
if err := cmd.Run(); err != nil {
getty.GetLogger().Errorf("Restart error %+v", err)
log.Run().Errorf("Restart error %+v", err)
}
}
......@@ -6,6 +6,7 @@ import (
"time"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
"virjar.com/majora-go/model"
)
......@@ -15,34 +16,43 @@ const (
)
func Redial(cfg *model.Configure, session getty.Session) {
getty.GetLogger().Warnf("[redial] start, session is close :%d", session.IsClosed())
log.Run().Infof("[redial] start, session is close :%d", session.IsClosed())
beforeIp := GetPPP()
retry := 0
defer func(start time.Time) {
newIp := GetPPP()
getty.GetLogger().Warnf("[redial] retry %d, cost %v, ip change %s -> %s, session is close:%v",
log.Run().Infof("[redial] retry %d, cost %v, ip change %s -> %s, session is close:%v",
retry, time.Since(start), beforeIp, newIp, session.IsClosed())
}(time.Now())
for {
retry++
status := command(cfg)
pingBaidu := PingBaidu()
getty.GetLogger().Warnf("[redial] net check: %d->%v", retry, pingBaidu)
pingBaidu := RandomPing()
log.Run().Infof("[redial] net check: %d->%v", retry, pingBaidu)
if pingBaidu && status {
break
}
}
}
func RedialByCheck(cfg *model.Configure) bool {
beforeIp := GetPPP()
defer func(start time.Time) {
newIp := GetPPP()
log.Run().Infof("[RedialByCheck] cost %v, ip change %s -> %s", time.Since(start), beforeIp, newIp)
}(time.Now())
return command(cfg)
}
func command(cfg *model.Configure) bool {
execPath := cfg.Redial.ExecPath
if len(execPath) == 0 {
getty.GetLogger().Warn("[redial] exec file is empty")
log.Run().Warn("[redial] exec file is empty")
return true
}
command := cfg.Redial.Command
if len(command) == 0 {
getty.GetLogger().Warn("[redial] command is empty")
log.Run().Warn("[redial] command is empty")
return true
}
......@@ -54,9 +64,9 @@ func command(cfg *model.Configure) bool {
cmd := exec.Command(command, args, execPath)
output, err := cmd.Output()
if err != nil {
getty.GetLogger().Errorf("[redial] Execute Shell:%s failed with error:%s", command, err.Error())
log.Run().Errorf("[redial] Execute Shell:%s failed with error:%s", command, err.Error())
return false
}
getty.GetLogger().Warnf("[redial] success %+v resp:%s", cmd, string(output))
log.Run().Infof("[redial] success %+v resp:%s", cmd, string(output))
return true
}
package infra
//// getBinary 下载二进制
//func getBinary(name, os, arch, version string) (io.ReadCloser, error) {
// fileName := fmt.Sprintf(common.VersionTpl, name, version, os, arch)
// if os == "windows" {
// fileName += ".exe"
// }
// url := common.UpdateServer + common.UpdateBinaryPath + fileName
// getty.GetLogger().Debugf("getBinary url %s, filename %s", url, fileName)
//
// body, err := http.DefaultClient.Get(url)
// if err != nil {
// return nil, err
// }
// return body.Body, nil
//}
//
//func downloadFile(name, os, arch, version string, f *os.File) error {
// binary, err := getBinary(name, os, arch, version)
// if err != nil {
// return err
// }
//
// defer func(binary io.ReadCloser) {
// _ = binary.Close()
// }(binary)
//
// body, err := ioutil.ReadAll(binary)
//
// if err != nil {
// return err
// }
//
// cnt, err := f.Write(body)
// if err != nil {
// return err
// }
//
// if cnt != len(body) {
// return errors.New("write to file is not enough")
// }
// return nil
//}
//
//func rename(src, dst string) error {
// if err := os.Chmod(src, common.DefaultMode); err != nil {
// return err
// }
//
// if err := os.Rename(src, dst); err != nil {
// return err
// }
// getty.GetLogger().Debugf("rename %s to %s", src, dst)
// return nil
//}
//
//func UpdateCore(name, latestVer, targetFile string) (bool, error) {
// tf, err := ioutil.TempFile("", "")
// if err != nil {
// getty.GetLogger().Debugf("UpdateCore TempFile with error %s", err.Error())
// return false, err
// }
//
// if err := downloadFile(name, runtime.GOOS, runtime.GOARCH, latestVer, tf); err != nil {
// getty.GetLogger().Debugf("UpdateCore downloadFile with error %s", err.Error())
// return false, err
// }
//
// if err := tf.Close(); err != nil {
// getty.GetLogger().Debugf("UpdateCore tf close with error %s", err.Error())
// return false, err
// }
//
// if err := rename(tf.Name(), targetFile); err != nil {
// return false, err
// }
// Restart()
// return true, nil
//}
//
//func getLatestVersion() (string, error) {
// url := common.UpdateServer + common.UpdateBinaryPath + common.Latest
// getty.GetLogger().Debugf("getLatestVersion from %s", url)
// resp, err := http.DefaultClient.Get(url) //nolint:bodyclose
// if err != nil || resp == nil {
// return "", err
// }
//
// defer func(Body io.ReadCloser) {
// _ = Body.Close()
// }(resp.Body)
//
// if resp.StatusCode != http.StatusOK {
// getty.GetLogger().Errorf("get latest version with error %s->%d", url, resp.StatusCode)
// return "", nil
// }
//
// bytes, err := ioutil.ReadAll(resp.Body)
// if err != nil {
// return "", err
// }
//
// return strings.ReplaceAll(string(bytes), "\n", ""), nil
//}
//
//func needUpdate(curVer string) (bool, string) {
// if len(curVer) == 0 {
// return false, ""
// }
// latestVer, err := getLatestVersion()
// if err != nil {
// getty.GetLogger().Errorf("getLatestVersion with error %s", err.Error())
// return false, ""
// }
//
// if len(latestVer) == 0 {
// getty.GetLogger().Errorf("getLatestVersion with empty")
// return false, ""
// }
//
// if curVer[0] == 'v' || curVer[0] == 'V' {
// curVer = curVer[1:]
// }
//
// latest := latestVer
// if latestVer[0] == 'v' || latestVer[0] == 'V' {
// latest = latest[1:]
// }
// cur, _ := semver.Make(curVer)
// next, _ := semver.Make(latest)
// getty.GetLogger().Debugf("curVer %s->cur %s, latestVer %s->next %s", curVer, cur, latest, next)
//
// return cur.Compare(next) < 0, latestVer
//}
//
//// Update update to the latest version
//func Update(name, curVer string) (bool, error) {
// defer func() {
// if err := recover(); err != nil {
// getty.GetLogger().Errorf("Update with error %+v", err)
// }
// }()
//
// // get current exec path
// executable, err := os.Executable()
// if err != nil {
// return false, err
// }
//
// getty.GetLogger().Debugf("current exec info %s", executable)
//
// // check has new version
// needUpdate, latestVer := needUpdate(curVer)
// getty.GetLogger().Debugf("curVer %s, latestVer %s, need update %v", curVer, latestVer, needUpdate)
// if !needUpdate {
// getty.GetLogger().Debugf("no need update ...")
// return false, nil
// }
// updateStatus, err := UpdateCore(name, latestVer, executable)
// if err != nil {
// getty.GetLogger().Errorf("update to latest version with error %s", err)
// return false, err
// }
// getty.GetLogger().Infof("update from %s to %s with success %v", curVer, latestVer, updateStatus)
// return updateStatus, nil
//}
package log
import (
"os"
"path/filepath"
"github.com/adamweixuan/getty"
)
var (
runLogger getty.Logger
eventLogger getty.Logger
heartLogger getty.Logger
latencyLogger getty.Logger
)
const (
logDir = "./output/log/"
run = "run.log"
event = "event.log"
heart = "heart.log"
latency = "latency.log"
)
func getCurPath() string {
exePath, err := os.Executable()
if err != nil {
panic(err)
}
return filepath.Dir(exePath)
}
func Init(level int) {
curPath := getCurPath()
base := filepath.Join(curPath, logDir)
if _, err := os.Stat(base); err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(base, os.ModePerm); err != nil {
panic(err)
}
} else {
panic(err)
}
}
if len(curPath) == 0 {
panic("invalid current path")
}
runLogger = getty.NewLogger(filepath.Join(base, run), getty.LoggerLevel(level))
eventLogger = getty.NewLogger(filepath.Join(base, event), getty.LoggerLevel(level))
heartLogger = getty.NewLogger(filepath.Join(base, heart), getty.LoggerLevel(level))
latencyLogger = getty.NewLogger(filepath.Join(base, latency), getty.LoggerLevel(level))
}
func Run() getty.Logger {
return runLogger
}
func Event() getty.Logger {
return eventLogger
}
func Heart() getty.Logger {
return heartLogger
}
func Latency() getty.Logger {
return latencyLogger
}
......@@ -3,7 +3,6 @@ package model
import (
"time"
"github.com/adamweixuan/getty"
"github.com/google/uuid"
"gopkg.in/ini.v1"
"virjar.com/majora-go/common"
......@@ -21,7 +20,6 @@ type Extra struct {
}
type Configure struct {
DisableUpdate bool `ini:"disable_update" json:"disable_update"`
LogLevel int `ini:"log_level" json:"log_level"`
PprofPort int `ini:"pprof_port" json:"pprof_port"`
TunnelAddr string `ini:"tunnel_addr" json:"tunnel_addr"`
......@@ -29,8 +27,8 @@ type Configure struct {
LocalAddr string `ini:"local_ip" json:"local_ip"`
ReconnInterval time.Duration `ini:"reconn_interval" json:"reconn_interval"`
ClientID string `ini:"client_id" json:"client_id"`
LogPath string `ini:"log_path" json:"log_path"`
NetCheckInterval time.Duration `ini:"net_check_interval" json:"net_check_interval"`
NetCheckUrl string `ini:"net_check_url" json:"net_check_url"`
Extra Extra `ini:"extra" json:"extra"`
Redial Redial `ini:"redial" json:"redial"`
}
......@@ -41,7 +39,6 @@ const (
func NewDefMajoraConf() *Configure {
return &Configure{
DisableUpdate: false,
LogLevel: 1,
PprofPort: 0,
TunnelAddr: common.DefNatAddr,
......@@ -60,7 +57,7 @@ func NewDefMajoraConf() *Configure {
func InitConf(path string) *Configure {
conf := NewDefMajoraConf()
if err := ini.MapTo(conf, path); err != nil {
getty.GetLogger().Errorf("InitConf with error %s, use default...", err.Error())
panic(err)
}
return conf
}
......
......@@ -3,8 +3,8 @@ package protocol
import (
"bufio"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/common"
"virjar.com/majora-go/log"
)
type Decoder interface {
......@@ -33,7 +33,7 @@ func (mpd *MajoraPacketDecoder) Decode(reader *bufio.Reader) (pack *MajoraPacket
// type
msgType, err := common.ReadByte(reader)
if err != nil {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
return nil, common.ErrInvalidSize
}
pack = &MajoraPacket{}
......@@ -42,20 +42,20 @@ func (mpd *MajoraPacketDecoder) Decode(reader *bufio.Reader) (pack *MajoraPacket
// num
pack.SerialNumber, err = common.ReadInt64(reader)
if err != nil {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
return nil, common.ErrInvalidSize
}
// extra size
extraSize, err := common.ReadByte(reader)
if err != nil {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
return nil, common.ErrInvalidSize
}
extra, err := common.ReadN(int(extraSize), reader)
if err != nil {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
return nil, common.ErrInvalidSize
}
pack.Extra = string(extra)
......@@ -63,14 +63,14 @@ func (mpd *MajoraPacketDecoder) Decode(reader *bufio.Reader) (pack *MajoraPacket
// dataFrame
dataSize := int(frameLen) - common.TypeSize - common.SerialNumberSize - common.ExtraSize - int(extraSize)
if dataSize < 0 {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
return nil, common.ErrInvalidSize
}
if dataSize > 0 {
data, err := common.ReadN(dataSize, reader)
if err != nil {
getty.GetLogger().Errorf("read type error %+v", err)
log.Run().Errorf("read type error %+v", err)
}
pack.Data = data
}
......
......@@ -3,7 +3,7 @@ package protocol
import (
"bytes"
"github.com/adamweixuan/getty"
"virjar.com/majora-go/log"
)
func EncodeExtra(extra map[string]string) []byte {
......@@ -33,7 +33,7 @@ func DecodeExtra(input []byte) map[string]string {
headerSize, err := buffer.ReadByte()
if err != nil {
getty.GetLogger().Errorf("DecodeExtra error %+v", err)
log.Run().Errorf("DecodeExtra error %+v", err)
return map[string]string{}
}
data := make(map[string]string)
......
package protocol
import (
"reflect"
"testing"
)
func TestEncodeExtra(t *testing.T) {
data := make(map[string]string)
data["hello"] = "world"
data["1"] = "world1"
data["2"] = "world2"
data["3"] = "world3"
data["account"] = "superman"
extra := EncodeExtra(data)
decodeExtra := DecodeExtra(extra)
t.Logf("TestEncodeExtra %+v", decodeExtra)
t.Logf("equal %v", reflect.DeepEqual(data, decodeExtra))
}
# v0.0.3
- [x] 重播 功能
- [x] 执行脚本 执行间隔
- [ ] http2 fix 抓包
- [x] 重连时间 可配置
- [x] 线程安全check
- [x] 支持config 文件
- [x] 代码的bug fix write/flush
- [ ] control
\ No newline at end of file
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