nps/server/server.go

267 lines
5.6 KiB
Go

package server
import (
"errors"
"github.com/astaxie/beego"
"github.com/cnlh/easyProxy/bridge"
"github.com/cnlh/easyProxy/utils"
"log"
"reflect"
"strings"
"sync"
)
type RunServer struct {
flag int //标志
ExportFlow int64 //出口流量
InletFlow int64 //入口流量
service interface{}
sync.Mutex
}
var (
Bridge *bridge.Bridge
RunList map[int]interface{} //运行中的任务
CsvDb = utils.GetCsvDb()
)
func init() {
RunList = make(map[int]interface{})
}
//从csv文件中恢复任务
func InitFromCsv() {
for _, v := range CsvDb.Tasks {
if v.Status {
log.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
AddTask(v)
}
}
}
//start a new server
func StartNewServer(bridgePort int, cnf *utils.Tunnel) {
Bridge = bridge.NewTunnel(bridgePort, RunList)
if err := Bridge.StartTunnel(); err != nil {
log.Fatalln("服务端开启失败", err)
}
if svr := NewMode(Bridge, cnf); svr != nil {
RunList[cnf.Id] = svr
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
log.Println(err)
}
} else {
log.Fatalln("启动模式不正确")
}
}
//new a server by mode name
func NewMode(Bridge *bridge.Bridge, c *utils.Tunnel) interface{} {
switch c.Mode {
case "tunnelServer":
return NewTunnelModeServer(ProcessTunnel, Bridge, c)
case "socks5Server":
return NewSock5ModeServer(Bridge, c)
case "httpProxyServer":
return NewTunnelModeServer(ProcessHttp, Bridge, c)
case "udpServer":
return NewUdpModeServer(Bridge, c)
case "webServer":
InitFromCsv()
p, _ := beego.AppConfig.Int("hostPort")
t := &utils.Tunnel{
TcpPort: p,
Mode: "httpHostServer",
Target: "",
Config: &utils.Config{},
Status: true,
}
AddTask(t)
return NewWebServer(Bridge)
case "hostServer":
return NewHostServer(c)
case "httpHostServer":
return NewTunnelModeServer(ProcessHost, Bridge, c)
}
return nil
}
//stop server
func StopServer(id int) error {
if v, ok := RunList[id]; ok {
reflect.ValueOf(v).MethodByName("Close").Call(nil)
if t, err := CsvDb.GetTask(id); err != nil {
return err
} else {
t.Status = false
CsvDb.UpdateTask(t)
}
return nil
}
return errors.New("未在运行中")
}
//add task
func AddTask(t *utils.Tunnel) error {
if svr := NewMode(Bridge, t); svr != nil {
RunList[t.Id] = svr
go func() {
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
log.Println("客户端", t.Id, "启动失败,错误:", err)
delete(RunList, t.Id)
}
}()
} else {
return errors.New("启动模式不正确")
}
return nil
}
//start task
func StartTask(id int) error {
if t, err := CsvDb.GetTask(id); err != nil {
return err
} else {
AddTask(t)
t.Status = true
CsvDb.UpdateTask(t)
}
return nil
}
//delete task
func DelTask(id int) error {
if err := StopServer(id); err != nil {
return err
}
return CsvDb.DelTask(id)
}
//get key by host from x
func GetInfoByHost(host string) (h *utils.Host, err error) {
for _, v := range CsvDb.Hosts {
s := strings.Split(host, ":")
if s[0] == v.Host {
h = v
return
}
}
err = errors.New("未找到host对应的内网目标")
return
}
//get task list by page num
func GetTunnel(start, length int, typeVal string, clientId int) ([]*utils.Tunnel, int) {
list := make([]*utils.Tunnel, 0)
var cnt int
for _, v := range CsvDb.Tasks {
if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
continue
}
cnt++
if _, ok := Bridge.SignalList[v.Client.Id]; ok {
v.Client.IsConnect = true
} else {
v.Client.IsConnect = false
}
if start--; start < 0 {
if length--; length > 0 {
if _, ok := RunList[v.Id]; ok {
v.Client.Status = true
} else {
v.Client.Status = false
}
list = append(list, v)
}
}
}
return list, cnt
}
//获取客户端列表
func GetClientList(start, length int) (list []*utils.Client, cnt int) {
list, cnt = CsvDb.GetClientList(start, length)
dealClientData(list)
return
}
func dealClientData(list []*utils.Client) {
for _, v := range list {
if _, ok := Bridge.SignalList[v.Id]; ok {
v.IsConnect = true
} else {
v.IsConnect = false
}
v.Flow.InletFlow = 0
v.Flow.ExportFlow = 0
for _, h := range CsvDb.Hosts {
if h.Client.Id == v.Id {
v.Flow.InletFlow += h.Flow.InletFlow
v.Flow.ExportFlow += h.Flow.ExportFlow
}
}
for _, t := range CsvDb.Tasks {
if t.Client.Id == v.Id {
v.Flow.InletFlow += t.Flow.InletFlow
v.Flow.ExportFlow += t.Flow.ExportFlow
}
}
}
return
}
//根据客户端id删除其所属的所有隧道和域名
func DelTunnelAndHostByClientId(clientId int) {
for _, v := range CsvDb.Tasks {
if v.Client.Id == clientId {
DelTask(v.Id)
}
}
for _, v := range CsvDb.Hosts {
if v.Client.Id == clientId {
CsvDb.DelHost(v.Host)
}
}
}
//关闭客户端连接
func DelClientConnect(clientId int) {
Bridge.DelClientTunnel(clientId)
Bridge.DelClientSignal(clientId)
}
func GetDashboardData() map[string]int {
data := make(map[string]int)
data["hostCount"] = len(CsvDb.Hosts)
data["clientCount"] = len(CsvDb.Clients)
list := CsvDb.Clients
dealClientData(list)
c := 0
var in, out int64
for _, v := range list {
if v.IsConnect {
c += 1
}
in += v.Flow.InletFlow
out += v.Flow.ExportFlow
}
data["clientOnlineCount"] = c
data["inletFlowCount"] = int(in)
data["exportFlowCount"] = int(out)
for _, v := range CsvDb.Tasks {
switch v.Mode {
case "tunnelServer":
data["tunnelServerCount"] += 1
case "socks5Server":
data["socks5ServerCount"] += 1
case "httpProxyServer":
data["httpProxyServerCount"] += 1
case "udpServer":
data["udpServerCount"] += 1
}
}
return data
}