初次提交
This commit is contained in:
+743
@@ -0,0 +1,743 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"rakshasa/aes"
|
||||
"rakshasa/cert"
|
||||
"rakshasa/common"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
bufPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &bytes.Buffer{}
|
||||
},
|
||||
}
|
||||
closeChan = make(chan *bytes.Buffer, 1) //用于接收已关闭消息的黑洞chan
|
||||
)
|
||||
|
||||
// 节点的连接,包含listen来的和主动connect的
|
||||
type Conn struct {
|
||||
closeTag int32
|
||||
node *node
|
||||
nodeaddr string
|
||||
//key string
|
||||
remoteAddr string
|
||||
inChan chan func()
|
||||
OutChan chan []byte
|
||||
close chan string
|
||||
isClient bool
|
||||
nodeConn *tls.Conn
|
||||
regResult chan error
|
||||
regResultNode chan *node
|
||||
}
|
||||
|
||||
type serverListen struct {
|
||||
close int32
|
||||
node *node
|
||||
listen net.Listener
|
||||
isSocks5 bool
|
||||
socks5Replay []byte
|
||||
replayid uint32
|
||||
id uint32
|
||||
connMap sync.Map
|
||||
}
|
||||
type serverConnect struct {
|
||||
close int32
|
||||
id uint32
|
||||
windowsSize int64
|
||||
conn net.Conn
|
||||
node *node
|
||||
address string
|
||||
|
||||
write chan *bytes.Buffer
|
||||
|
||||
wait chan int
|
||||
closeReason string
|
||||
}
|
||||
|
||||
// 中转与最终出口
|
||||
func StartServer(port int) error {
|
||||
config := cert.Tlsconfig.Clone()
|
||||
fmt.Println("start on port:", port)
|
||||
|
||||
l, err := tls.Listen("tcp", ":"+strconv.Itoa(port), config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("server start fail %v", err)
|
||||
}
|
||||
currentNode.listen = l
|
||||
go func() {
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
if err.(*net.OpError).Err == net.ErrClosed {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
//封装一个符合common.server接口的server
|
||||
|
||||
c := &Conn{
|
||||
nodeConn: conn.(*tls.Conn),
|
||||
remoteAddr: conn.RemoteAddr().String(),
|
||||
}
|
||||
connMap.Store(c.remoteAddr, conn)
|
||||
go c.handlerNodeRead()
|
||||
go c.handle()
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
func init() {
|
||||
go func() {
|
||||
for b := range closeChan {
|
||||
b.Reset()
|
||||
bufPool.Put(b)
|
||||
}
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
func (conn *serverConnect) Close(reason string) {
|
||||
if atomic.CompareAndSwapInt32(&conn.close, 0, 1) {
|
||||
go func() {
|
||||
if conn.conn != nil {
|
||||
conn.conn.Close()
|
||||
}
|
||||
//fmt.Println(conn.fd, reason)
|
||||
conn.node.connMap.Delete(conn.id)
|
||||
conn.closeReason = reason
|
||||
conn.node.listenMap.Range(func(key, value interface{}) bool {
|
||||
value.(*serverListen).connMap.Delete(conn.id)
|
||||
return true
|
||||
})
|
||||
if reason != remoteClose {
|
||||
conn.node.Write(common.CMD_DELETE_CONNID, conn.id, nil)
|
||||
}
|
||||
|
||||
select {
|
||||
case conn.wait <- common.CONN_STATUS_CLOSE:
|
||||
case <-time.After(time.Second * 10):
|
||||
}
|
||||
conn.write <- nil
|
||||
conn.write = closeChan
|
||||
|
||||
}()
|
||||
}
|
||||
}
|
||||
func (c *Conn) Close(reason string) {
|
||||
|
||||
c.close <- reason
|
||||
|
||||
}
|
||||
|
||||
func (conn *serverConnect) handTcpReceive() {
|
||||
go func() {
|
||||
for b := range conn.write {
|
||||
if b == nil {
|
||||
conn.write = closeChan
|
||||
return
|
||||
}
|
||||
if _, err := conn.conn.Write(b.Bytes()); err != nil {
|
||||
conn.Close(err.Error())
|
||||
}
|
||||
b.Reset()
|
||||
bufPool.Put(b)
|
||||
}
|
||||
}()
|
||||
var err error
|
||||
var n int
|
||||
defer func() {
|
||||
|
||||
if err != nil {
|
||||
conn.Close(conn.address + " 读取出错" + err.Error())
|
||||
} else {
|
||||
conn.Close(conn.address + " read异常关闭")
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
buf := make([]byte, common.MAX_PLAINTEXT)
|
||||
|
||||
for conn.close == 0 {
|
||||
conn.conn.SetReadDeadline(time.Now().Add(common.WRITE_DEADLINE))
|
||||
n, err = conn.conn.Read(buf)
|
||||
if err != nil {
|
||||
if atomic.LoadInt32(&conn.close) == 0 {
|
||||
if e := err.Error(); !strings.Contains(e, ": i/o timeout") {
|
||||
|
||||
return
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
data := make([]byte, n)
|
||||
copy(data, buf)
|
||||
if common.Debug {
|
||||
|
||||
fmt.Println("发送", crc32.ChecksumIEEE(data), n)
|
||||
}
|
||||
conn.node.Write(common.CMD_CONN_MSG, conn.id, data)
|
||||
|
||||
atomic.AddInt64(&conn.windowsSize, -1*int64(n))
|
||||
|
||||
for atomic.LoadInt64(&conn.windowsSize) <= 0 && conn.close == 0 {
|
||||
|
||||
select {
|
||||
case flag := <-conn.wait:
|
||||
if flag == common.CONN_STATUS_CLOSE {
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func (conn *serverConnect) Write(data []byte) {
|
||||
data = data[1:]
|
||||
windows_update_size := int64(data[0]) | int64(data[1])<<8 | int64(data[2])<<16 | int64(data[3])<<24 | int64(data[4])<<32 | int64(data[5])<<40 | int64(data[6])<<48 | int64(data[7])<<56
|
||||
|
||||
if windows_update_size != 0 {
|
||||
|
||||
old := atomic.AddInt64(&conn.windowsSize, windows_update_size) - windows_update_size
|
||||
if old < 0 {
|
||||
go func() {
|
||||
select {
|
||||
case conn.wait <- common.CONN_STATUS_OK:
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
if common.Debug {
|
||||
|
||||
fmt.Println("收到", crc32.ChecksumIEEE(data[8:]), len(data[8:]))
|
||||
}
|
||||
b := bufPool.Get().(*bytes.Buffer)
|
||||
b.Reset()
|
||||
b.Write(data[8:])
|
||||
conn.write <- b
|
||||
}
|
||||
func (conn *serverConnect) handUdpReceive() {
|
||||
|
||||
var err error
|
||||
var n int
|
||||
defer func() {
|
||||
|
||||
if err != nil {
|
||||
conn.Close(conn.address + " 网站读取出错" + err.Error())
|
||||
} else {
|
||||
conn.Close(conn.address + " read异常关闭")
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
buf := make([]byte, common.MAX_PLAINTEXT)
|
||||
|
||||
for conn.close == 0 {
|
||||
conn.conn.SetReadDeadline(time.Now().Add(common.WRITE_DEADLINE))
|
||||
n, err = conn.conn.Read(buf)
|
||||
if err != nil {
|
||||
if atomic.LoadInt32(&conn.close) == 0 {
|
||||
if e := err.Error(); !strings.Contains(e, ": i/o timeout") {
|
||||
|
||||
return
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
b := make([]byte, n)
|
||||
copy(b, buf)
|
||||
conn.node.Write(common.CMD_CONN_UDP_MSG, conn.id, b)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (conn *serverConnect) doConnectTcp(network common.NetWork, addr string) {
|
||||
|
||||
netconn, err := net.DialTimeout("tcp", addr, time.Second*30)
|
||||
if err != nil {
|
||||
buf := make([]byte, 2)
|
||||
buf[0] = byte(network)
|
||||
buf[1] = 0
|
||||
conn.node.Write(common.CMD_CONNECT_BYIDADDR_RESULT, conn.id, buf)
|
||||
conn.Close("fd拨号失败")
|
||||
return
|
||||
} else {
|
||||
buf := make([]byte, 2)
|
||||
buf[0] = byte(network)
|
||||
buf[1] = 1
|
||||
conn.node.Write(common.CMD_CONNECT_BYIDADDR_RESULT, conn.id, buf)
|
||||
if conn.close == 0 {
|
||||
conn.conn = netconn
|
||||
go conn.handTcpReceive()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
func (conn *serverConnect) doConnectTcpWithHttpProxy(network common.NetWork, addr string) {
|
||||
writeResult := func(res bool) {
|
||||
buf := make([]byte, 2)
|
||||
buf[0] = byte(network)
|
||||
buf[1] = 0
|
||||
if res {
|
||||
buf[1] = 1
|
||||
}
|
||||
conn.node.Write(common.CMD_CONNECT_BYIDADDR_RESULT, conn.id, buf)
|
||||
}
|
||||
|
||||
if i := strings.IndexByte(addr, 32); i > -1 {
|
||||
cfg, err := common.ParseAddr(addr[i+1:])
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("地址解析失败")
|
||||
return
|
||||
}
|
||||
netconn, err := net.DialTimeout("tcp", cfg.Addr(), time.Second*2)
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("fd拨号失败")
|
||||
return
|
||||
} else {
|
||||
netconn.SetDeadline(time.Now().Add(time.Second * 30))
|
||||
netconn.SetWriteDeadline(time.Now().Add(time.Second * 30))
|
||||
switch cfg.Scheam() {
|
||||
case "", "http://":
|
||||
//请求代理
|
||||
data := fmt.Sprintf("CONNECT %s HTTP/1.1\r\nHost: %s\r\nProxy-Connection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\r\n", addr[:i], addr[:i])
|
||||
if cfg.GetHttpAuthorizationHeader() != "" {
|
||||
data += cfg.GetHttpAuthorizationHeader() + "\r\n\r\n"
|
||||
} else {
|
||||
data += "\r\n"
|
||||
}
|
||||
_, err = netconn.Write([]byte(data))
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("http代理发送消息失败")
|
||||
return
|
||||
}
|
||||
var resdata []byte
|
||||
var result [8192]byte
|
||||
var req = &http1request{}
|
||||
for {
|
||||
n, err := netconn.Read(result[:])
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("读取http代理结果失败")
|
||||
return
|
||||
}
|
||||
resdata = append(resdata, result[:n]...)
|
||||
l, _, err := parsereq(req, resdata)
|
||||
if err != nil {
|
||||
return
|
||||
} else if l > 0 {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if req.Status == "200 Connection established" {
|
||||
writeResult(true)
|
||||
if conn.close == 0 {
|
||||
conn.conn = netconn
|
||||
go conn.handTcpReceive()
|
||||
|
||||
}
|
||||
} else {
|
||||
writeResult(false)
|
||||
conn.Close("http代理连接失败")
|
||||
}
|
||||
writeResult(true)
|
||||
case "socks5://":
|
||||
_, err = netconn.Write([]byte{5, 1, 2})
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("socks5代理发送消息失败")
|
||||
return
|
||||
}
|
||||
var result [8192]byte
|
||||
|
||||
n, err := netconn.Read(result[:])
|
||||
if err != nil {
|
||||
writeResult(false)
|
||||
conn.Close("读取socks5数据出错")
|
||||
return
|
||||
}
|
||||
|
||||
if string(result[:n]) == string([]byte{5, 2}) { //需要认证
|
||||
user, password := cfg.User(), cfg.Password()
|
||||
if user == "" && password == "" {
|
||||
writeResult(false)
|
||||
conn.Close("socks5需要验证")
|
||||
return
|
||||
}
|
||||
|
||||
data := make([]byte, (3 + len(user) + len(password)))
|
||||
data[0] = 5
|
||||
data[1] = byte(len(user))
|
||||
copy(data[2:], user)
|
||||
data[2+len(user)] = byte(len(password))
|
||||
copy(data[3+len(user):], password)
|
||||
netconn.Write(data)
|
||||
n, err = netconn.Read(result[:])
|
||||
if err != nil || string(result[:n]) != string([]byte{5, 0}) {
|
||||
writeResult(false)
|
||||
conn.Close("密码校验不通过")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
data := []byte{5, 1, 0, 1}
|
||||
if u, err := url.ParseRequestURI(addr[:i]); err == nil {
|
||||
data[3] = 3
|
||||
data = append(data, byte(len(u.Scheme)))
|
||||
data = append(data, u.Scheme...)
|
||||
p, _ := strconv.Atoi(u.Opaque)
|
||||
port := []byte{byte(p >> 8), byte(p)}
|
||||
data = append(data, port...)
|
||||
} else if tcp4, err := net.ResolveTCPAddr("tcp4", addr[:i]); err == nil {
|
||||
data[3] = 1
|
||||
data = append(data, tcp4.IP.String()...)
|
||||
port := []byte{byte(tcp4.Port), byte(tcp4.Port >> 8)}
|
||||
data = append(data, port...)
|
||||
} else if tcp6, err := net.ResolveTCPAddr("tcp6", addr[:i]); err == nil {
|
||||
data[3] = 4
|
||||
data = append(data, tcp6.IP.String()...)
|
||||
port := []byte{byte(tcp6.Port), byte(tcp6.Port >> 8)}
|
||||
data = append(data, port...)
|
||||
}
|
||||
netconn.Write(data)
|
||||
n, _ = netconn.Read(result[:])
|
||||
if n >= 2 && string(result[:2]) == string([]byte{5, 0}) {
|
||||
writeResult(true)
|
||||
if conn.close == 0 {
|
||||
conn.conn = netconn
|
||||
go conn.handTcpReceive()
|
||||
|
||||
}
|
||||
} else {
|
||||
writeResult(false)
|
||||
conn.Close("socks5连接失败")
|
||||
}
|
||||
|
||||
default:
|
||||
writeResult(false)
|
||||
conn.Close("不支持的代理协议")
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
writeResult(false)
|
||||
conn.Close("无法获取代理地址")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (conn *serverConnect) doHandleUdp() {
|
||||
for b := range conn.write {
|
||||
if b == nil {
|
||||
conn.write = closeChan
|
||||
return
|
||||
}
|
||||
|
||||
conn.conn.Write(b.Bytes())
|
||||
b.Reset()
|
||||
bufPool.Put(b)
|
||||
}
|
||||
}
|
||||
|
||||
var broadcastMap sync.Map //广播帧防止重复处理
|
||||
func (c *Conn) handlerNodeRead() {
|
||||
var err error
|
||||
defer func() {
|
||||
c.nodeConn.Close()
|
||||
c.Close("read错误" + err.Error())
|
||||
|
||||
}()
|
||||
|
||||
lengbuf := make([]byte, 2)
|
||||
for {
|
||||
_, err = io.ReadFull(c.nodeConn, lengbuf)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "i/o timeout") {
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, int(lengbuf[0])+int(lengbuf[1])<<8)
|
||||
_, err = io.ReadFull(c.nodeConn, buf)
|
||||
b := aes.AesCtrDecrypt(buf)
|
||||
msg := common.UnmarshalMsg(b)
|
||||
if common.Debug {
|
||||
fmt.Println("fromto", msg.From, msg.To, common.CmdToName[msg.CmdOpteion])
|
||||
}
|
||||
|
||||
if msg.To == common.NoneUUID.String() && c.node == nil {
|
||||
c.inChan <- func() {
|
||||
newNode := &node{
|
||||
conn: c,
|
||||
}
|
||||
newNode.do(msg)
|
||||
}
|
||||
} else if msg.To == currentNode.uuid {
|
||||
func() {
|
||||
l := clientLock.RLock()
|
||||
v, ok := nodeMap[msg.From]
|
||||
l.RUnlock()
|
||||
if ok && v.port > 0 {
|
||||
c.inChan <- func() {
|
||||
v.do(msg)
|
||||
}
|
||||
} else {
|
||||
l := clientLock.Lock()
|
||||
v, ok := nodeMap[msg.From]
|
||||
if !ok {
|
||||
newNode := &node{
|
||||
uuid: msg.From,
|
||||
conn: c,
|
||||
waitMsg: []*common.Msg{msg},
|
||||
}
|
||||
result := make(chan interface{}, 1)
|
||||
id := newNode.storeQuery(result)
|
||||
nodeMap[msg.From] = newNode
|
||||
l.Unlock()
|
||||
newNode.Write(common.CMD_GET_CURRENT_NODE, id, []byte{1}) //获取丢失节点的信息
|
||||
go func() {
|
||||
defer newNode.deleteQuery(id)
|
||||
select {
|
||||
case res := <-result:
|
||||
if res == nil {
|
||||
|
||||
for _, m := range newNode.waitMsg {
|
||||
c.inChan <- func() {
|
||||
newNode.do(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
case <-time.After(common.CMD_TIMEOUT):
|
||||
newNode.Delete("超时")
|
||||
}
|
||||
}()
|
||||
|
||||
} else {
|
||||
|
||||
if msg.CmdOpteion == common.CMD_GET_CURRENT_NODE_RESULT {
|
||||
|
||||
var res chan interface{}
|
||||
if _v, ok := v.loadQuery(msg.CmdId); !ok {
|
||||
return
|
||||
} else {
|
||||
res = _v
|
||||
}
|
||||
|
||||
var nmsg nodeMsg
|
||||
err = json.Unmarshal(msg.CmdData, &nmsg)
|
||||
if err != nil {
|
||||
res <- err
|
||||
return
|
||||
}
|
||||
|
||||
v.hostName = nmsg.HostName
|
||||
v.uuid = nmsg.UUID
|
||||
v.port = nmsg.Port
|
||||
v.mainIp = nmsg.MainIp
|
||||
v.goos = nmsg.Goos
|
||||
if nmsg.Addr != "" {
|
||||
v.addr = nmsg.Addr
|
||||
}
|
||||
res <- nil
|
||||
} else {
|
||||
v.waitMsg = append(v.waitMsg, msg)
|
||||
}
|
||||
|
||||
l.Unlock()
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
} else {
|
||||
|
||||
key := msg.From + "_" + strconv.Itoa(int(msg.MsgId))
|
||||
msg.Ttl++
|
||||
if _, ok := broadcastMap.LoadOrStore(key, struct{}{}); !ok {
|
||||
|
||||
if msg.From != currentNode.uuid && msg.To == common.BroadcastUUID.String() && msg.Ttl < 250 { //广播
|
||||
go allNodesDo(func(_n *node) (bool, error) {
|
||||
if _n.uuid != currentNode.uuid {
|
||||
_n.WriteMsg(msg)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
newNode := &node{
|
||||
conn: c,
|
||||
}
|
||||
c.inChan <- func() {
|
||||
newNode.do(msg)
|
||||
}
|
||||
} else {
|
||||
c.WriteToUUID(msg)
|
||||
}
|
||||
time.AfterFunc(time.Hour, func() {
|
||||
broadcastMap.Delete(key)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conn) handle() {
|
||||
c.OutChan = make(chan []byte, 64)
|
||||
c.inChan = make(chan func())
|
||||
|
||||
c.close = make(chan string, 999)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case f := <-c.inChan:
|
||||
f()
|
||||
//c.do(b)
|
||||
case b := <-c.OutChan:
|
||||
|
||||
if c.closeTag == 0 {
|
||||
c.tlsWrite(b)
|
||||
//var err error
|
||||
for i := 0; i < len(c.OutChan); i++ {
|
||||
|
||||
c.tlsWrite(<-c.OutChan)
|
||||
}
|
||||
}
|
||||
|
||||
case reason := <-c.close:
|
||||
c.OutChan = upNodeWrite
|
||||
if c.node != nil && c.node.nextPingTime > time.Now().Unix()+5 {
|
||||
c.node.ping(0)
|
||||
c.node.nextPingTime = time.Now().Unix() + 5
|
||||
}
|
||||
func() { //返回false则退出handle
|
||||
connMap.Delete(c.remoteAddr)
|
||||
l := clientLock.Lock()
|
||||
defer func() {
|
||||
l.Unlock()
|
||||
}()
|
||||
|
||||
if atomic.CompareAndSwapInt32(&c.closeTag, 0, 1) {
|
||||
if common.Debug {
|
||||
fmt.Println(c.nodeConn.RemoteAddr().String(), "关闭原因", reason)
|
||||
}
|
||||
if c.nodeConn != nil {
|
||||
|
||||
c.nodeConn.Close()
|
||||
}
|
||||
|
||||
if c.node != nil {
|
||||
//移除上游连接
|
||||
for i := len(upLevelNode) - 1; i >= 0; i-- {
|
||||
n := upLevelNode[i]
|
||||
if n.uuid == c.node.uuid {
|
||||
upLevelNode = append(upLevelNode[:i], upLevelNode[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
func (c *Conn) reg() error {
|
||||
|
||||
if c.nodeConn != nil {
|
||||
c.nodeConn.Close()
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.nodeConn, err = tls.Dial("tcp", c.nodeaddr, cert.Tlsconfig.Clone())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reg := common.RegMsg{
|
||||
RegAddr: c.nodeaddr,
|
||||
Addr: currentNode.addr,
|
||||
UUID: currentNode.uuid,
|
||||
MainIp: currentNode.mainIp,
|
||||
Port: currentNode.port,
|
||||
Goos: currentNode.goos,
|
||||
}
|
||||
reg.Hostname, _ = os.Hostname()
|
||||
|
||||
regb, _ := json.Marshal(reg)
|
||||
msg := common.Msg{
|
||||
From: currentNode.uuid,
|
||||
To: common.NoneUUID.String(),
|
||||
CmdOpteion: common.CMD_REG,
|
||||
CmdData: regb,
|
||||
}
|
||||
|
||||
if err = c.tlsWrite(msg.Marshal()); err != nil {
|
||||
return err
|
||||
}
|
||||
go c.handlerNodeRead()
|
||||
return nil
|
||||
}
|
||||
func (c *Conn) WriteToUUID(msg *common.Msg) {
|
||||
|
||||
l := clientLock.RLock()
|
||||
defer l.RUnlock()
|
||||
|
||||
if n, ok := nodeMap[msg.To]; ok {
|
||||
n.WriteMsg(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conn) Write(b []byte) {
|
||||
|
||||
c.OutChan <- b
|
||||
}
|
||||
|
||||
func (c *Conn) tlsWrite(b []byte) error {
|
||||
c.nodeConn.SetWriteDeadline(time.Now().Add(common.WRITE_DEADLINE))
|
||||
n, err := c.nodeConn.Write(b)
|
||||
if common.Debug {
|
||||
fmt.Println("tlsWrite发送", n)
|
||||
}
|
||||
if err != nil {
|
||||
c.Close("Write " + err.Error())
|
||||
upNodeWrite <- b
|
||||
}
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user