2019-01-09 12:33:00 +00:00
|
|
|
|
package bridge
|
|
|
|
|
|
|
|
|
|
import (
|
2019-02-12 19:54:00 +00:00
|
|
|
|
"encoding/binary"
|
2019-01-09 12:33:00 +00:00
|
|
|
|
"errors"
|
2019-02-16 12:43:26 +00:00
|
|
|
|
"fmt"
|
2019-02-12 19:54:00 +00:00
|
|
|
|
"github.com/cnlh/nps/lib/common"
|
2019-02-09 09:07:47 +00:00
|
|
|
|
"github.com/cnlh/nps/lib/conn"
|
2019-02-12 19:54:00 +00:00
|
|
|
|
"github.com/cnlh/nps/lib/crypt"
|
2019-02-09 09:07:47 +00:00
|
|
|
|
"github.com/cnlh/nps/lib/file"
|
|
|
|
|
"github.com/cnlh/nps/lib/lg"
|
|
|
|
|
"github.com/cnlh/nps/lib/pool"
|
2019-02-12 19:54:00 +00:00
|
|
|
|
"github.com/cnlh/nps/server/tool"
|
2019-02-16 12:43:26 +00:00
|
|
|
|
"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
|
2019-02-12 19:54:00 +00:00
|
|
|
|
"log"
|
2019-01-09 12:33:00 +00:00
|
|
|
|
"net"
|
2019-02-09 09:07:47 +00:00
|
|
|
|
"strconv"
|
2019-01-09 12:33:00 +00:00
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
type Client struct {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
tunnel *conn.Conn
|
|
|
|
|
signal *conn.Conn
|
2019-02-17 11:36:48 +00:00
|
|
|
|
msg *conn.Conn
|
2019-02-09 09:07:47 +00:00
|
|
|
|
linkMap map[int]*conn.Link
|
2019-01-31 18:06:30 +00:00
|
|
|
|
linkStatusMap map[int]bool
|
|
|
|
|
stop chan bool
|
|
|
|
|
sync.RWMutex
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-17 11:36:48 +00:00
|
|
|
|
func NewClient(t *conn.Conn, s *conn.Conn, m *conn.Conn) *Client {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
return &Client{
|
|
|
|
|
linkMap: make(map[int]*conn.Link),
|
|
|
|
|
stop: make(chan bool),
|
|
|
|
|
linkStatusMap: make(map[int]bool),
|
|
|
|
|
signal: s,
|
|
|
|
|
tunnel: t,
|
2019-02-17 11:36:48 +00:00
|
|
|
|
msg: m,
|
2019-02-09 09:07:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-26 09:27:28 +00:00
|
|
|
|
type Bridge struct {
|
2019-02-16 12:43:26 +00:00
|
|
|
|
TunnelPort int //通信隧道端口
|
|
|
|
|
tcpListener *net.TCPListener //server端监听
|
|
|
|
|
kcpListener *kcp.Listener //server端监听
|
|
|
|
|
Client map[int]*Client
|
|
|
|
|
tunnelType string //bridge type kcp or tcp
|
|
|
|
|
OpenTask chan *file.Tunnel
|
|
|
|
|
CloseClient chan int
|
|
|
|
|
clientLock sync.RWMutex
|
|
|
|
|
Register map[string]time.Time
|
|
|
|
|
registerLock sync.RWMutex
|
|
|
|
|
ipVerify bool
|
2019-02-16 15:18:58 +00:00
|
|
|
|
runList map[int]interface{}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-16 15:18:58 +00:00
|
|
|
|
func NewTunnel(tunnelPort int, tunnelType string, ipVerify bool, runList map[int]interface{}) *Bridge {
|
2019-01-26 09:27:28 +00:00
|
|
|
|
t := new(Bridge)
|
2019-01-09 12:33:00 +00:00
|
|
|
|
t.TunnelPort = tunnelPort
|
2019-01-31 18:06:30 +00:00
|
|
|
|
t.Client = make(map[int]*Client)
|
2019-02-09 09:07:47 +00:00
|
|
|
|
t.tunnelType = tunnelType
|
2019-02-12 19:54:00 +00:00
|
|
|
|
t.OpenTask = make(chan *file.Tunnel)
|
|
|
|
|
t.CloseClient = make(chan int)
|
2019-02-16 12:43:26 +00:00
|
|
|
|
t.Register = make(map[string]time.Time)
|
|
|
|
|
t.ipVerify = ipVerify
|
2019-02-16 15:18:58 +00:00
|
|
|
|
t.runList = runList
|
2019-01-09 12:33:00 +00:00
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-26 09:27:28 +00:00
|
|
|
|
func (s *Bridge) StartTunnel() error {
|
2019-01-09 12:33:00 +00:00
|
|
|
|
var err error
|
2019-02-09 09:07:47 +00:00
|
|
|
|
if s.tunnelType == "kcp" {
|
|
|
|
|
s.kcpListener, err = kcp.ListenWithOptions(":"+strconv.Itoa(s.TunnelPort), nil, 150, 3)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
c, err := s.kcpListener.AcceptKCP()
|
|
|
|
|
conn.SetUdpSession(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
lg.Println(err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
go s.cliProcess(conn.NewConn(c))
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
} else {
|
|
|
|
|
s.tcpListener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.TunnelPort, ""})
|
2019-01-09 12:33:00 +00:00
|
|
|
|
if err != nil {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
return err
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-02-09 09:07:47 +00:00
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
c, err := s.tcpListener.Accept()
|
|
|
|
|
if err != nil {
|
|
|
|
|
lg.Println(err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
go s.cliProcess(conn.NewConn(c))
|
|
|
|
|
}
|
|
|
|
|
}()
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-02-09 09:07:47 +00:00
|
|
|
|
return nil
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//验证失败,返回错误验证flag,并且关闭连接
|
2019-02-09 09:07:47 +00:00
|
|
|
|
func (s *Bridge) verifyError(c *conn.Conn) {
|
|
|
|
|
c.Write([]byte(common.VERIFY_EER))
|
2019-01-09 12:33:00 +00:00
|
|
|
|
c.Conn.Close()
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-12 19:54:00 +00:00
|
|
|
|
func (s *Bridge) verifySuccess(c *conn.Conn) {
|
|
|
|
|
c.Write([]byte(common.VERIFY_SUCCESS))
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 09:07:47 +00:00
|
|
|
|
func (s *Bridge) cliProcess(c *conn.Conn) {
|
|
|
|
|
c.SetReadDeadline(5, s.tunnelType)
|
2019-01-28 06:45:55 +00:00
|
|
|
|
var buf []byte
|
|
|
|
|
var err error
|
|
|
|
|
if buf, err = c.ReadLen(32); err != nil {
|
|
|
|
|
c.Close()
|
|
|
|
|
return
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-01-28 06:45:55 +00:00
|
|
|
|
//验证
|
2019-02-09 09:07:47 +00:00
|
|
|
|
id, err := file.GetCsvDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
|
2019-01-25 04:10:12 +00:00
|
|
|
|
if err != nil {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
lg.Println("当前客户端连接校验错误,关闭此客户端:", c.Conn.RemoteAddr())
|
2019-01-09 12:33:00 +00:00
|
|
|
|
s.verifyError(c)
|
2019-01-28 06:45:55 +00:00
|
|
|
|
return
|
2019-02-12 19:54:00 +00:00
|
|
|
|
} else {
|
|
|
|
|
s.verifySuccess(c)
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
//做一个判断 添加到对应的channel里面以供使用
|
2019-01-28 06:45:55 +00:00
|
|
|
|
if flag, err := c.ReadFlag(); err == nil {
|
|
|
|
|
s.typeDeal(flag, c, id)
|
2019-02-12 19:54:00 +00:00
|
|
|
|
} else {
|
|
|
|
|
log.Println(err, flag)
|
2019-01-28 06:45:55 +00:00
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Bridge) closeClient(id int) {
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
defer s.clientLock.Unlock()
|
|
|
|
|
if v, ok := s.Client[id]; ok {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
if c, err := file.GetCsvDb().GetClient(id); err == nil && c.NoStore {
|
|
|
|
|
s.CloseClient <- c.Id
|
|
|
|
|
}
|
2019-01-31 18:06:30 +00:00
|
|
|
|
v.signal.WriteClose()
|
|
|
|
|
delete(s.Client, id)
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-17 11:36:48 +00:00
|
|
|
|
func (s *Bridge) delClient(id int) {
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
defer s.clientLock.Unlock()
|
|
|
|
|
if v, ok := s.Client[id]; ok {
|
|
|
|
|
if c, err := file.GetCsvDb().GetClient(id); err == nil && c.NoStore {
|
|
|
|
|
s.CloseClient <- c.Id
|
|
|
|
|
}
|
|
|
|
|
v.signal.Close()
|
|
|
|
|
delete(s.Client, id)
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
|
|
|
|
|
//tcp连接类型区分
|
2019-02-09 09:07:47 +00:00
|
|
|
|
func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
|
2019-01-09 12:33:00 +00:00
|
|
|
|
switch typeVal {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
case common.WORK_MAIN:
|
2019-01-28 06:45:55 +00:00
|
|
|
|
//客户端已经存在,下线
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Lock()
|
2019-02-09 09:07:47 +00:00
|
|
|
|
if v, ok := s.Client[id]; ok {
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Unlock()
|
2019-02-09 09:07:47 +00:00
|
|
|
|
if v.signal != nil {
|
|
|
|
|
v.signal.WriteClose()
|
|
|
|
|
}
|
|
|
|
|
v.Lock()
|
|
|
|
|
v.signal = c
|
|
|
|
|
v.Unlock()
|
2019-01-31 18:06:30 +00:00
|
|
|
|
} else {
|
2019-02-17 11:36:48 +00:00
|
|
|
|
s.Client[id] = NewClient(nil, c, nil)
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
}
|
2019-02-12 19:54:00 +00:00
|
|
|
|
lg.Printf("clientId %d connection succeeded, address:%s ", id, c.Conn.RemoteAddr())
|
2019-01-31 18:06:30 +00:00
|
|
|
|
go s.GetStatus(id)
|
2019-02-09 09:07:47 +00:00
|
|
|
|
case common.WORK_CHAN:
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
if v, ok := s.Client[id]; ok {
|
|
|
|
|
s.clientLock.Unlock()
|
2019-02-09 09:07:47 +00:00
|
|
|
|
v.Lock()
|
2019-01-31 18:06:30 +00:00
|
|
|
|
v.tunnel = c
|
2019-02-09 09:07:47 +00:00
|
|
|
|
v.Unlock()
|
2019-01-31 18:06:30 +00:00
|
|
|
|
} else {
|
2019-02-17 11:36:48 +00:00
|
|
|
|
s.Client[id] = NewClient(c, nil, nil)
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
go s.clientCopy(id)
|
2019-02-12 19:54:00 +00:00
|
|
|
|
case common.WORK_CONFIG:
|
|
|
|
|
go s.GetConfig(c)
|
2019-02-16 12:43:26 +00:00
|
|
|
|
case common.WORK_REGISTER:
|
|
|
|
|
go s.register(c)
|
2019-02-17 11:36:48 +00:00
|
|
|
|
case common.WORK_SEND_STATUS:
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
if v, ok := s.Client[id]; ok {
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
v.Lock()
|
|
|
|
|
v.msg = c
|
|
|
|
|
v.Unlock()
|
|
|
|
|
} else {
|
|
|
|
|
s.Client[id] = NewClient(nil, nil, c)
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
go s.getMsgStatus(id)
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-02-09 09:07:47 +00:00
|
|
|
|
c.SetAlive(s.tunnelType)
|
2019-01-28 06:45:55 +00:00
|
|
|
|
return
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-17 11:36:48 +00:00
|
|
|
|
func (s *Bridge) getMsgStatus(clientId int) {
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
client := s.Client[clientId]
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
|
|
|
|
|
if client == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
for {
|
|
|
|
|
if id, err := client.msg.GetLen(); err != nil {
|
|
|
|
|
s.closeClient(clientId)
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
client.Lock()
|
|
|
|
|
if v, ok := client.linkMap[id]; ok {
|
|
|
|
|
v.StatusCh <- true
|
|
|
|
|
}
|
|
|
|
|
client.Unlock()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-16 12:43:26 +00:00
|
|
|
|
func (s *Bridge) register(c *conn.Conn) {
|
|
|
|
|
var hour int32
|
|
|
|
|
if err := binary.Read(c, binary.LittleEndian, &hour); err == nil {
|
|
|
|
|
s.registerLock.Lock()
|
|
|
|
|
s.Register[common.GetIpByAddr(c.Conn.RemoteAddr().String())] = time.Now().Add(time.Hour * time.Duration(hour))
|
|
|
|
|
s.registerLock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
//等待
|
2019-02-16 12:43:26 +00:00
|
|
|
|
func (s *Bridge) waitStatus(clientId, id int) bool {
|
2019-01-31 18:06:30 +00:00
|
|
|
|
ticker := time.NewTicker(time.Millisecond * 100)
|
|
|
|
|
stop := time.After(time.Second * 10)
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-ticker.C:
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
if v, ok := s.Client[clientId]; ok {
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
v.Lock()
|
|
|
|
|
if vv, ok := v.linkStatusMap[id]; ok {
|
|
|
|
|
ticker.Stop()
|
|
|
|
|
v.Unlock()
|
|
|
|
|
return vv
|
|
|
|
|
}
|
|
|
|
|
v.Unlock()
|
|
|
|
|
} else {
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
case <-stop:
|
|
|
|
|
return false
|
|
|
|
|
}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-16 12:43:26 +00:00
|
|
|
|
func (s *Bridge) SendLinkInfo(clientId int, link *conn.Link, linkAddr string) (tunnel *conn.Conn, err error) {
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
if v, ok := s.Client[clientId]; ok {
|
|
|
|
|
s.clientLock.Unlock()
|
2019-02-16 12:43:26 +00:00
|
|
|
|
if s.ipVerify {
|
|
|
|
|
s.registerLock.Lock()
|
|
|
|
|
ip := common.GetIpByAddr(linkAddr)
|
|
|
|
|
if v, ok := s.Register[ip]; !ok {
|
|
|
|
|
s.registerLock.Unlock()
|
|
|
|
|
return nil, errors.New(fmt.Sprintf("The ip %s is not in the validation list", ip))
|
|
|
|
|
} else {
|
|
|
|
|
if !v.After(time.Now()) {
|
|
|
|
|
return nil, errors.New(fmt.Sprintf("The validity of the ip %s has expired", ip))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s.registerLock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
v.signal.SendLinkInfo(link)
|
|
|
|
|
if err != nil {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
lg.Println("send link information error:", err, link.Id)
|
2019-01-31 18:06:30 +00:00
|
|
|
|
s.DelClient(clientId)
|
|
|
|
|
return
|
|
|
|
|
}
|
2019-02-17 11:36:48 +00:00
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
if v.tunnel == nil {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
err = errors.New("get tunnel connection error")
|
2019-01-31 18:06:30 +00:00
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
tunnel = v.tunnel
|
|
|
|
|
}
|
2019-02-17 11:36:48 +00:00
|
|
|
|
link.MsgConn = v.msg
|
2019-01-31 18:06:30 +00:00
|
|
|
|
v.Lock()
|
|
|
|
|
v.linkMap[link.Id] = link
|
|
|
|
|
v.Unlock()
|
|
|
|
|
if !s.waitStatus(clientId, link.Id) {
|
2019-02-17 11:55:24 +00:00
|
|
|
|
err = errors.New(fmt.Sprintf("connect target %s fail", link.Host))
|
2019-01-31 18:06:30 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
s.clientLock.Unlock()
|
2019-02-12 19:54:00 +00:00
|
|
|
|
err = errors.New("the connection is not connect")
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-01-31 18:06:30 +00:00
|
|
|
|
return
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//删除通信通道
|
2019-01-31 18:06:30 +00:00
|
|
|
|
func (s *Bridge) DelClient(id int) {
|
|
|
|
|
s.closeClient(id)
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-12 19:54:00 +00:00
|
|
|
|
//get config
|
|
|
|
|
func (s *Bridge) GetConfig(c *conn.Conn) {
|
|
|
|
|
var client *file.Client
|
|
|
|
|
var fail bool
|
|
|
|
|
for {
|
|
|
|
|
flag, err := c.ReadFlag()
|
|
|
|
|
if err != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
switch flag {
|
|
|
|
|
case common.WORK_STATUS:
|
|
|
|
|
if b, err := c.ReadLen(16); err != nil {
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
var str string
|
|
|
|
|
id, err := file.GetCsvDb().GetClientIdByVkey(string(b))
|
|
|
|
|
if err != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
for _, v := range file.GetCsvDb().Hosts {
|
|
|
|
|
if v.Client.Id == id {
|
|
|
|
|
str += v.Remark + common.CONN_DATA_SEQ
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, v := range file.GetCsvDb().Tasks {
|
2019-02-16 15:18:58 +00:00
|
|
|
|
if _, ok := s.runList[v.Id]; ok && v.Client.Id == id {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
str += v.Remark + common.CONN_DATA_SEQ
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
binary.Write(c, binary.LittleEndian, int32(len([]byte(str))))
|
|
|
|
|
binary.Write(c, binary.LittleEndian, []byte(str))
|
|
|
|
|
}
|
|
|
|
|
case common.NEW_CONF:
|
|
|
|
|
//new client ,Set the client not to store to the file
|
|
|
|
|
client = file.NewClient(crypt.GetRandomString(16), true, false)
|
|
|
|
|
client.Remark = "public veky"
|
|
|
|
|
//Send the key to the client
|
|
|
|
|
file.GetCsvDb().NewClient(client)
|
|
|
|
|
c.Write([]byte(client.VerifyKey))
|
|
|
|
|
|
|
|
|
|
if config, err := c.GetConfigInfo(); err != nil {
|
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
client.Cnf = config
|
|
|
|
|
c.WriteAddOk()
|
|
|
|
|
}
|
|
|
|
|
case common.NEW_HOST:
|
|
|
|
|
if h, err := c.GetHostInfo(); err != nil {
|
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
|
|
|
|
break
|
2019-02-16 12:43:26 +00:00
|
|
|
|
} else if file.GetCsvDb().IsHostExist(h) {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
|
|
|
|
} else {
|
|
|
|
|
h.Client = client
|
|
|
|
|
file.GetCsvDb().NewHost(h)
|
|
|
|
|
c.WriteAddOk()
|
|
|
|
|
}
|
|
|
|
|
case common.NEW_TASK:
|
|
|
|
|
if t, err := c.GetTaskInfo(); err != nil {
|
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
|
|
|
|
break
|
|
|
|
|
} else {
|
2019-02-15 14:59:28 +00:00
|
|
|
|
ports := common.GetPorts(t.Ports)
|
|
|
|
|
targets := common.GetPorts(t.Target)
|
|
|
|
|
if len(ports) > 1 && (t.Mode == "tcpServer" || t.Mode == "udpServer") && (len(ports) != len(targets)) {
|
2019-02-12 19:54:00 +00:00
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
2019-02-15 14:59:28 +00:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
for i := 0; i < len(ports); i++ {
|
|
|
|
|
tl := new(file.Tunnel)
|
|
|
|
|
tl.Mode = t.Mode
|
|
|
|
|
tl.Port = ports[i]
|
|
|
|
|
if len(ports) == 1 {
|
|
|
|
|
tl.Target = t.Target
|
2019-02-16 15:18:58 +00:00
|
|
|
|
tl.Remark = t.Remark
|
2019-02-15 14:59:28 +00:00
|
|
|
|
} else {
|
2019-02-16 15:18:58 +00:00
|
|
|
|
tl.Remark = t.Remark + "_" + strconv.Itoa(tl.Port)
|
2019-02-15 14:59:28 +00:00
|
|
|
|
tl.Target = strconv.Itoa(targets[i])
|
|
|
|
|
}
|
|
|
|
|
tl.Id = file.GetCsvDb().GetTaskId()
|
|
|
|
|
tl.Status = true
|
|
|
|
|
tl.Flow = new(file.Flow)
|
|
|
|
|
tl.NoStore = true
|
|
|
|
|
tl.Client = client
|
|
|
|
|
file.GetCsvDb().NewTask(tl)
|
|
|
|
|
if b := tool.TestServerPort(tl.Port, tl.Mode); !b {
|
|
|
|
|
fail = true
|
|
|
|
|
c.WriteAddFail()
|
|
|
|
|
} else {
|
|
|
|
|
s.OpenTask <- tl
|
|
|
|
|
}
|
|
|
|
|
c.WriteAddOk()
|
2019-02-12 19:54:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-12 19:54:00 +00:00
|
|
|
|
if fail && client != nil {
|
|
|
|
|
s.CloseClient <- client.Id
|
|
|
|
|
}
|
|
|
|
|
c.Close()
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
2019-02-12 19:54:00 +00:00
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
func (s *Bridge) GetStatus(clientId int) {
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
client := s.Client[clientId]
|
|
|
|
|
s.clientLock.Unlock()
|
2019-01-09 12:33:00 +00:00
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
if client == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
for {
|
2019-01-31 18:06:30 +00:00
|
|
|
|
if id, status, err := client.signal.GetConnStatus(); err != nil {
|
|
|
|
|
s.closeClient(clientId)
|
2019-01-12 16:09:12 +00:00
|
|
|
|
return
|
2019-01-31 18:06:30 +00:00
|
|
|
|
} else {
|
|
|
|
|
client.Lock()
|
|
|
|
|
client.linkStatusMap[id] = status
|
|
|
|
|
client.Unlock()
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 18:06:30 +00:00
|
|
|
|
func (s *Bridge) clientCopy(clientId int) {
|
|
|
|
|
|
|
|
|
|
s.clientLock.Lock()
|
|
|
|
|
client := s.Client[clientId]
|
|
|
|
|
s.clientLock.Unlock()
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
if id, err := client.tunnel.GetLen(); err != nil {
|
2019-02-17 11:36:48 +00:00
|
|
|
|
lg.Println("read msg content length error close client")
|
|
|
|
|
s.delClient(clientId)
|
2019-01-31 18:06:30 +00:00
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
client.Lock()
|
|
|
|
|
if link, ok := client.linkMap[id]; ok {
|
|
|
|
|
client.Unlock()
|
|
|
|
|
if content, err := client.tunnel.GetMsgContent(link); err != nil {
|
2019-02-09 09:07:47 +00:00
|
|
|
|
pool.PutBufPoolCopy(content)
|
2019-02-17 11:36:48 +00:00
|
|
|
|
s.delClient(clientId)
|
2019-02-09 09:07:47 +00:00
|
|
|
|
lg.Println("read msg content error", err, "close client")
|
2019-01-31 18:06:30 +00:00
|
|
|
|
break
|
|
|
|
|
} else {
|
2019-02-17 11:36:48 +00:00
|
|
|
|
link.MsgCh <- content
|
2019-01-31 18:06:30 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
client.Unlock()
|
|
|
|
|
continue
|
|
|
|
|
}
|
2019-01-09 12:33:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|