181 lines
3.9 KiB
Go
181 lines
3.9 KiB
Go
package server
|
|
|
|
import (
|
|
"cert"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"math/rand"
|
|
"net"
|
|
"rakshasa_lite/common"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
// clientListenMap = make(map[uint32]*remoteListen)
|
|
// connectMap = make(map[uint32]*rawConnect)
|
|
)
|
|
|
|
type clientListen struct {
|
|
id uint32
|
|
localAddr string
|
|
remoteAddr string
|
|
server *node
|
|
typ string
|
|
openOption byte
|
|
openMsg []byte //掉线重连会用到
|
|
connMap sync.Map //clientListen关闭的时候关掉这里的id
|
|
listen net.Listener
|
|
result chan interface{}
|
|
randkey []byte //随机key int64
|
|
}
|
|
|
|
func StartRawBind(str string, dst []string) error {
|
|
n, err := GetNodeFromAddrs(dst)
|
|
if err != nil {
|
|
|
|
return err
|
|
}
|
|
|
|
addrs, err := common.ResolveTCPAddr(str)
|
|
if err != nil {
|
|
|
|
return err
|
|
}
|
|
if len(addrs) != 2 {
|
|
return errors.New("参数错误,格式为ip:port,remote_ip:remote_port")
|
|
}
|
|
|
|
l := &clientListen{
|
|
id: common.GetID(),
|
|
localAddr: addrs[0],
|
|
remoteAddr: addrs[1],
|
|
server: n,
|
|
typ: "bind",
|
|
result: make(chan interface{}),
|
|
openOption: common.CMD_LISTEN,
|
|
randkey: make([]byte, 8),
|
|
}
|
|
binary.LittleEndian.PutUint64(l.randkey, uint64(rand.NewSource(time.Now().UnixNano()).Int63()))
|
|
l.openMsg = cert.RSAEncrypterByPrivByte(append(l.randkey, []byte(addrs[1])...))
|
|
currentNode.listenMap.Store(l.id, l)
|
|
n.Write(l.openOption, l.id, l.openMsg)
|
|
select {
|
|
case res := <-l.result:
|
|
|
|
if err, ok := res.(error); ok {
|
|
l.Close(remoteClose)
|
|
currentNode.listenMap.Delete(l.id)
|
|
return err
|
|
}
|
|
case <-time.After(common.CMD_TIMEOUT):
|
|
l.Close(remoteClose)
|
|
currentNode.listenMap.Delete(l.id)
|
|
return fmt.Errorf("listen %s fail time out", addrs[1])
|
|
|
|
}
|
|
fmt.Println("bind 启动成功")
|
|
//l := clientLock.Lock()
|
|
|
|
//clientListenMap[b.id] = b
|
|
//l.Unlock()
|
|
return nil
|
|
}
|
|
func StartRawConnect(str string, n *node) error {
|
|
addrs, err := common.ResolveTCPAddr(str)
|
|
if len(addrs) != 2 || err != nil {
|
|
return errors.New("-connect参数错误,格式为ip:port,remote_ip:remote_port")
|
|
}
|
|
|
|
addr1, _ := net.ResolveTCPAddr("tcp", addrs[1])
|
|
listen, err := net.Listen("tcp", addrs[0])
|
|
if err != nil {
|
|
return errors.New("监听本地端口" + addrs[0] + "失败 " + err.Error())
|
|
}
|
|
|
|
l := &clientListen{
|
|
id: common.GetID(),
|
|
localAddr: addrs[0],
|
|
remoteAddr: addrs[1],
|
|
listen: listen,
|
|
server: n,
|
|
typ: "connect",
|
|
randkey: make([]byte, 8),
|
|
}
|
|
binary.LittleEndian.PutUint64(l.randkey, uint64(rand.NewSource(time.Now().UnixNano()).Int63()))
|
|
currentNode.listenMap.Store(l.id, l)
|
|
|
|
go func() {
|
|
for {
|
|
conn, err := listen.Accept()
|
|
if err != nil {
|
|
if err.(*net.OpError).Err == net.ErrClosed {
|
|
return
|
|
}
|
|
continue
|
|
}
|
|
|
|
s := &clientConnect{
|
|
conn: conn,
|
|
server: n,
|
|
randkey: l.randkey,
|
|
}
|
|
s.OnOpened()
|
|
if s.connect(common.RAW_TCP, addr1.IP.String(), uint16(addr1.Port)) {
|
|
go rawHandleLocal(s)
|
|
} else {
|
|
s.Close(nodeIsClose)
|
|
|
|
}
|
|
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
func (l *clientListen) Close(reason string) {
|
|
l.connMap.Range(func(key, value interface{}) bool {
|
|
value.(*clientConnect).Close(reason)
|
|
l.connMap.Delete(key)
|
|
return true
|
|
})
|
|
l.server.listenMap.Delete(l.id)
|
|
if l.listen != nil {
|
|
l.listen.Close()
|
|
}
|
|
}
|
|
|
|
func rawHandleLocal(s *clientConnect) {
|
|
buf := make([]byte, common.MAX_PLAINTEXT)
|
|
|
|
for {
|
|
n, err := s.conn.Read(buf[8:])
|
|
if err != nil {
|
|
|
|
s.Close(err.Error())
|
|
return
|
|
}
|
|
|
|
var new_size int64
|
|
if new_size = int64(common.INIT_WINDOWS_SIZE) - s.windowsSize; new_size > 0 { //扩大窗口
|
|
atomic.AddInt64(&s.windowsSize, new_size)
|
|
|
|
} else {
|
|
new_size = 0
|
|
}
|
|
buf[0] = byte(new_size)
|
|
buf[1] = byte(new_size >> 8)
|
|
buf[2] = byte(new_size >> 16)
|
|
buf[3] = byte(new_size >> 24)
|
|
buf[4] = byte(new_size >> 32)
|
|
buf[5] = byte(new_size >> 40)
|
|
buf[6] = byte(new_size >> 48)
|
|
buf[7] = byte(new_size >> 56)
|
|
|
|
data := make([]byte, 8+n)
|
|
copy(data, buf)
|
|
s.server.Write(common.CMD_CONN_MSG, s.id, buf[:8+n])
|
|
}
|
|
}
|