This commit is contained in:
arraykeys
2019-08-08 17:13:34 +08:00
parent e8e5966a8c
commit f0bf2d5fec
2885 changed files with 1195993 additions and 12 deletions
+100
View File
@@ -0,0 +1,100 @@
package main
import (
utils "anytunnel/at-common"
"flag"
"fmt"
"os"
"strings"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
const APP_VERSION = "1.0.0"
var (
cfg = viper.New()
)
func initConfig() (err error) {
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
configFile := pflag.String("config", "", "config file path")
//发布时开启,开发时注释掉
// cfg.SetDefault("url", "https://atcloud.host900.com:29531/cluster/get")
cfg.SetDefault("url", "https://127.0.0.1:29531/cluster/get")
cfg.SetDefault("host", "127.0.0.1")
cfg.SetDefault("port.conns", 37501)
cfg.SetDefault("port.control", 37601)
//结束
//开发时开启,发布时注释掉
// pflag.String("url", "", "dispatch url of cluster to connecting")
// cfg.BindPFlag("url", pflag.Lookup("url"))
// pflag.String("host", "127.0.0.1", "host of cluster to connecting")
// cfg.BindPFlag("host", pflag.Lookup("host"))
// pflag.Int("conns-port", 37501, "port of cluster to connecting")
// cfg.BindPFlag("port.conns", pflag.Lookup("conns-port"))
// pflag.Int("control-port", 37601, "port of cluster to control")
// cfg.BindPFlag("port.control", pflag.Lookup("control-port"))
//结束
pflag.String("token", "", "token of client connect to cluster")
cfg.BindPFlag("token", pflag.Lookup("token"))
pflag.Int("udp-timeout", 2, "seconds of waiting for remote udp server reponse")
cfg.BindPFlag("udp.timeout", pflag.Lookup("udp-timeout"))
pflag.Bool("log-open", false, "if true: store log files, false: no log files")
pflag.String("level", "debug", "console log level,should be one of debug,info,warn,error")
pflag.String("log-dir", "log", "the directory which store log files")
pflag.Bool("log-post", false, "log post data on or off")
pflag.Int64("log-max-size", 102400000, "log file max size(bytes) for rotate")
pflag.Int("log-max-count", 3, "log file max count for rotate to remain")
pflag.StringSlice("log-level", []string{"info", "error", "debug"}, "log to file level,multiple splitted by comma(,)")
pflag.Parse()
cfg.BindPFlag("log.dir", pflag.Lookup("log-dir"))
cfg.BindPFlag("log.level", pflag.Lookup("log-level"))
cfg.BindPFlag("log.open", pflag.Lookup("log-open"))
cfg.BindPFlag("log.console-level", pflag.Lookup("level"))
cfg.BindPFlag("log.fileMaxSize", pflag.Lookup("log-max-size"))
cfg.BindPFlag("log.maxCount", pflag.Lookup("log-max-count"))
addr, err := utils.GetClusterHost(cfg.GetString("url"), cfg.GetString("token"), "client")
if err == nil {
cfg.Set("host", addr)
} else if cfg.GetString("url") != "" {
fmt.Printf("%s , please try again\n", err)
os.Exit(0)
}
if *configFile != "" {
cfg.SetConfigFile(*configFile)
} else {
cfg.SetConfigName("client")
cfg.AddConfigPath("/etc/anytunnel/")
cfg.AddConfigPath("$HOME/.anytunnel")
cfg.AddConfigPath(".anytunnel")
cfg.AddConfigPath(".")
}
err = cfg.ReadInConfig()
file := cfg.ConfigFileUsed()
if err != nil && !strings.Contains(err.Error(), "Not") {
fmt.Printf("%s", err)
} else if file != "" {
fmt.Printf("use config file : %s\n", file)
}
err = nil
return
}
func poster() {
fmt.Printf(`
╔═╗┌┐┌┬ ┬╔╦╗┬ ┬┌┐┌┌┐┌┌─┐┬ ╔═╗┬ ┬┌─┐┌┐┌┌┬┐
╠═╣│││└┬┘ ║ │ │││││││├┤ │───║ │ │├┤ │││ │
╩ ╩┘└┘ ┴ ╩ └─┘┘└┘┘└┘└─┘┴─┘ ╚═╝┴─┘┴└─┘┘└┘ ┴ v%s`+"\n\n", APP_VERSION)
}
+51
View File
@@ -0,0 +1,51 @@
package main
import (
utils "anytunnel/at-common"
"github.com/snail007/mini-logger"
"github.com/snail007/mini-logger/writers/console"
"github.com/snail007/mini-logger/writers/files"
)
var log logger.MiniLogger
//initLog
func initLog() {
var level uint8
switch cfg.GetString("log.console-level") {
case "debug":
level = logger.AllLevels
case "info":
level = logger.InfoLevel | logger.WarnLevel | logger.ErrorLevel | logger.FatalLevel
case "warn":
level = logger.WarnLevel | logger.ErrorLevel | logger.FatalLevel
case "error":
level = logger.ErrorLevel | logger.FatalLevel
case "fatal":
level = logger.FatalLevel
default:
level = 0
}
log = logger.New(false, nil)
log.AddWriter(console.NewDefault(), level)
cfgF := files.GetDefaultFileConfig()
cfgF.LogPath = cfg.GetString("log.dir")
cfgF.MaxBytes = cfg.GetInt64("log.FileMaxSize")
cfgF.MaxCount = cfg.GetInt("log.MaxCount")
cfgLevels := cfg.GetStringSlice("log.level")
if ok, _ := utils.InArray("debug", cfgLevels); ok {
cfgF.FileNameSet["debug"] = logger.AllLevels
}
if ok, _ := utils.InArray("info", cfgLevels); ok {
cfgF.FileNameSet["info"] = logger.InfoLevel
}
if ok, _ := utils.InArray("error", cfgLevels); ok {
cfgF.FileNameSet["error"] = logger.WarnLevel | logger.ErrorLevel | logger.FatalLevel
}
if cfg.GetBool("log.open") {
log.AddWriter(files.New(cfgF), logger.AllLevels)
}
}
+174
View File
@@ -0,0 +1,174 @@
package main
import (
utils "anytunnel/at-common"
"bufio"
"bytes"
"crypto/tls"
"encoding/binary"
"fmt"
"io"
"net"
"time"
logger "github.com/snail007/mini-logger"
)
var (
control utils.Author
err error
)
func init() {
poster()
initConfig()
initLog()
}
func main() {
defer func() {
e := recover()
if e != nil {
log.Errorf("Exit ERR:%s", e)
}
logger.Flush()
}()
control, err = utils.NewAuthor(cfg.GetString("token"), cfg.GetString("host"), cfg.GetInt("port.control"), utils.CSTYPE_CLIENT)
if err != nil {
log.Debugf("create author fail : %s", err)
return
}
control.Channel.SetMsgErrorHandler(func(channel *utils.MessageChannel, msg interface{}, err error) {
log.Warnf("message pre-process error , ERRR:%s", err)
})
control.Channel.RegMsg(utils.MSG_TYPE_PONG, new(utils.MsgPong), func(channel *utils.MessageChannel, msg interface{}) {
msgPong := msg.(*utils.MsgPong)
log.Infof("pong revecived , id : %s", msgPong.ID)
return
})
control.Channel.RegMsg(utils.MSG_CLIENT_OPEN_CONNECTION, new(utils.MsgClientOpenConnection), func(channel *utils.MessageChannel, msg interface{}) {
msgClientOpenConnection := msg.(*utils.MsgClientOpenConnection)
if msgClientOpenConnection.Protocol == utils.TUNNEL_PROTOCOL_TCP {
openConnection(channel, msgClientOpenConnection)
} else {
openUDPConnection(channel, msgClientOpenConnection)
}
})
control.Channel.DoServe(func(err error) {
//log.Fatalf("offline , disconnected from cluster , %s", err)
log.Fatalf("offline , disconnected from cluster .")
})
err = control.DoControlAuth()
if err != nil {
log.Fatalf("login fail : %s", err)
return
}
// log.Infof("login success %s - %s", control.Channel.LocalAddr(), control.Channel.RemoteAddr())
log.Infof("login success")
select {}
}
var clientClusterConnPool = utils.NewConcurrentMap()
func openUDPConnection(controlChannel *utils.MessageChannel, msg *utils.MsgClientOpenConnection) {
tunnleID := msg.TunnelID
connid := msg.ConnectinID
connidStr := fmt.Sprintf("%d", (*msg).ConnectinID)
var clusterConn *tls.Conn
_, ok := clientClusterConnPool.Get(connidStr)
if !ok {
_clusterConn, err := connectCluster(*msg)
if err != nil {
return
}
clusterConn = &_clusterConn
clientClusterConnPool.Set(connidStr, clusterConn)
log.Debugf("connection %d - %d created success", tunnleID, connid)
go func() {
for {
srcAddr, body, err := utils.ReadUDPPacket(clusterConn)
if err == io.EOF || err == io.ErrUnexpectedEOF {
log.Debugf("connection %d - %d released", tunnleID, connid)
clientClusterConnPool.Remove(connidStr)
break
}
func() {
//log.Debugf("udp packet revecived:%s,%v", srcAddr, body)
dstAddr := &net.UDPAddr{IP: net.ParseIP(msg.LocalHost), Port: msg.LocalPort}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil {
log.Warnf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return
}
conn.SetDeadline(time.Now().Add(time.Second * time.Duration(cfg.GetInt("udp.timeout"))))
_, err = conn.Write(body)
if err != nil {
log.Warnf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
return
}
//log.Debugf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 512)
len, _, err := conn.ReadFromUDP(buf)
if err != nil {
log.Warnf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
return
}
respBody := buf[0:len]
//log.Debugf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
_, err = clusterConn.Write(utils.UDPPacket(srcAddr, respBody))
if err != nil {
log.Warnf("send udp response to cluster fail ,ERR:%s", err)
return
}
//log.Debugf("send udp response to cluster success ,from:%s", dstAddr.String())
}()
}
}()
}
return
}
func openConnection(controlChannel *utils.MessageChannel, msg *utils.MsgClientOpenConnection) {
tunnleID := msg.TunnelID
connid := msg.ConnectinID
clusterConn, err := connectCluster(*msg)
if err != nil {
return
}
localConn, err := utils.Connect(msg.LocalHost, msg.LocalPort, 5000)
if err != nil {
log.Debugf("connection %d - %d created fail ,err:%s", tunnleID, connid, err)
clusterConn.Close()
return
}
utils.IoBind(localConn, &clusterConn, func(err error) {
localConn.Close()
clusterConn.Close()
log.Debugf("connection %d - %d released", tunnleID, connid)
}, func(bytesCount int, isPositive bool) {}, 0)
log.Debugf("connection %d - %d created success", tunnleID, connid)
return
}
func connectCluster(cmd utils.MsgClientOpenConnection) (clusterConn tls.Conn, err error) {
tunnleID := cmd.TunnelID
connid := cmd.ConnectinID
log.Debugf("new connection %d - %d", tunnleID, connid)
clusterConn, err = utils.TlsConnect(cfg.GetString("host"), cfg.GetInt("port.conns"), 3000)
if err != nil {
log.Warnf("connect to cluster fail ,err:%s", err)
return
}
writer := bufio.NewWriter(&clusterConn)
pkg := new(bytes.Buffer)
binary.Write(pkg, binary.LittleEndian, utils.CS_CLIENT)
binary.Write(pkg, binary.LittleEndian, tunnleID)
binary.Write(pkg, binary.LittleEndian, connid)
writer.Write(pkg.Bytes())
err = writer.Flush()
if err != nil {
log.Warnf("connect to cluster fail ,flush err:%s", err)
return
}
return
}