修复多节点连接的bug

This commit is contained in:
Mob2003
2023-03-28 11:38:55 +08:00
parent 36af6a8f50
commit e4b3295dce
11 changed files with 306 additions and 341 deletions
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13 -3
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"fmt"
"github.com/dlclark/regexp2"
"github.com/google/uuid"
"math/rand"
"net"
@@ -15,6 +16,7 @@ import (
)
var Debug bool = false
var NoPing bool = false
var DebugLock bool = false
var DebugLockMap sync.Map
@@ -194,13 +196,12 @@ func init() {
type RegMsg struct {
UUID string //当前机器uuid
Addr string
RegAddr string //远程连接的addr
Hostname string //当前机器名称
Goos string
ViaUUID string
Err string
MainIp []string
MainIp string
Port int
}
@@ -310,7 +311,16 @@ func ResolveTCPAddr(str string) ([]string, error) {
dst = append(dst[:i], dst[i+1:]...)
} else {
if _, err := net.ResolveTCPAddr("tcp", addr); err != nil {
return nil, fmt.Errorf("参数错误 格式为\"ip:端口\",多个地址以逗号隔开,错误详情%v", err)
if i>0{
r, _ := regexp2.Compile(`^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}`, 0)
match,_ :=r.MatchString(addr)
if !match{
return nil, fmt.Errorf("参数错误 格式为\"ip:端口\",多个地址以逗号隔开,错误详情%v", err)
}
}else{
return nil, fmt.Errorf("参数错误 格式为\"ip:端口,第二个地址可以是UUID\",多个地址以逗号隔开,错误详情%v", err)
}
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ type Config struct {
DstNode []string //-d 上级节点
Password string //通讯密码,可为空
Port int //默认8883
ListenIp []string //指定公网ip,其他节点进行额外节点连接时候,尝试连接的ip
ListenIp string //指定公网ip,其他节点进行额外节点连接时候,尝试连接的ip
Limit bool //禁止额外连接,只连接-d节点,不会尝试连接其他节点
FileName string
FileSave bool `yaml:"-"`
+16 -191
View File
@@ -8,194 +8,19 @@
66.29.154.103:3128
35.222.50.197:80
169.55.89.6:80
174.70.1.210:8080
35.209.198.222:80
208.109.32.60:81
3.134.56.120:80
20.241.236.196:3128
216.215.123.174:8080
3.128.142.113:80
146.190.74.6:80
24.106.221.230:53281
165.3.122.211:80
155.254.192.216:80
104.255.231.87:3128
45.61.163.12:80
45.77.198.163:80
216.137.184.253:80
71.255.153.117:80
104.223.135.178:10000
109.122.195.16:80
5.78.78.180:8080
54.82.79.59:80
52.24.80.166:80
3.220.76.84:80
129.153.107.221:80
64.225.8.115:9997
20.69.79.158:8443
191.101.1.116:80
5.78.75.64:8080
72.169.67.145:87
12.69.91.227:80
4.16.68.158:443
52.144.46.250:25345
198.59.191.234:8080
64.225.4.12:9991
93.188.166.232:80
137.184.197.190:80
72.169.67.241:87
130.41.109.158:8080
204.2.218.145:8080
66.75.121.167:8080
162.223.94.163:80
38.242.195.210:80
64.225.8.132:9979
93.188.161.84:80
68.183.143.134:80
64.225.8.142:9988
184.60.66.122:80
15.204.207.232:3128
64.225.4.81:9991
47.254.47.61:77
64.225.8.118:9990
31.220.52.49:80
23.238.33.186:80
52.86.21.254:80
103.152.112.145:80
3.12.178.169:80
47.88.87.74:1080
98.110.236.35:8080
142.93.61.46:80
154.202.97.224:3128
154.201.62.199:3128
154.202.122.29:3128
154.202.98.115:3128
72.169.66.157:87
75.89.101.62:80
64.225.8.121:9992
198.11.175.192:3128
159.89.132.167:8989
72.170.220.17:8080
148.76.97.250:80
3.94.182.57:7497
43.251.116.62:45787
206.189.199.91:80
34.23.45.223:80
64.225.4.63:9998
52.38.72.41:80
38.52.220.194:999
18.217.198.64:80
206.161.97.62:31337
170.187.138.40:8009
143.198.182.218:80
34.170.89.64:80
97.74.92.60:80
64.225.8.82:9995
43.249.11.114:45787
137.184.242.126:80
143.110.232.177:80
143.198.228.250:80
209.126.6.159:80
138.68.60.8:3128
63.239.220.11:8080
100.21.127.153:80
34.229.213.84:8118
45.81.130.51:45787
198.199.86.11:8080
108.161.128.43:80
209.169.71.193:80
64.225.8.191:9987
167.99.236.14:80
156.239.48.222:3128
209.127.148.104:3128
154.202.118.16:3128
154.202.124.35:3128
154.83.8.195:3128
154.202.125.108:3128
194.50.243.120:3128
154.202.127.66:3128
154.202.119.127:3128
156.239.48.48:3128
162.144.236.128:80
157.230.48.102:80
104.45.128.122:80
149.248.14.12:24018
72.169.67.85:87
128.199.13.74:80
64.225.4.29:9994
72.52.217.188:80
154.202.122.17:3128
154.202.127.8:3128
154.202.127.192:3128
154.202.115.109:3128
156.239.51.113:3128
154.202.119.154:3128
154.202.98.233:3128
154.201.61.223:3128
156.239.53.151:3128
154.202.97.174:3128
209.127.48.59:3128
156.239.48.128:3128
156.239.54.138:3128
154.202.125.44:3128
156.239.51.49:3128
154.202.113.77:3128
209.127.136.164:3128
154.202.122.139:3128
154.202.114.4:3128
45.199.137.179:3128
185.93.32.136:3128
45.199.140.87:3128
154.202.114.244:3128
156.239.55.233:3128
154.202.112.54:3128
156.239.51.131:3128
154.83.10.189:3128
154.83.8.13:3128
154.83.11.100:3128
154.202.112.128:3128
156.239.50.212:3128
154.202.110.19:3128
45.199.141.170:3128
154.202.113.221:3128
154.202.113.65:3128
45.199.140.85:3128
45.199.141.22:3128
50.114.110.124:3128
154.202.96.105:3128
154.202.114.110:3128
156.239.53.37:3128
156.239.55.63:3128
45.199.137.141:3128
154.202.118.60:3128
154.202.114.168:3128
45.199.140.71:3128
156.239.54.108:3128
154.202.114.20:3128
50.114.111.113:3128
156.239.53.217:3128
154.83.10.165:3128
45.199.139.158:3128
156.239.49.73:3128
154.202.112.20:3128
45.199.141.196:3128
154.202.98.241:3128
194.50.243.246:3128
154.201.63.43:3128
50.114.111.75:3128
154.202.111.153:3128
156.239.52.10:3128
156.239.51.17:3128
154.202.125.224:3128
156.239.54.78:3128
154.202.117.84:3128
154.83.9.218:3128
154.202.107.212:3128
156.239.53.11:3128
156.239.49.131:3128
154.202.118.72:3128
154.83.9.238:3128
45.199.141.60:3128
156.239.55.117:3128
154.202.120.165:3128
socks5://admin:[email protected]:1080
167.71.246.128:3128
129.21.158.30:8080
69.167.174.17:80
45.119.208.134:80
216.21.18.194:80
54.205.132.170:80
113.121.39.200:7890
54.222.237.192:8888
120.27.239.26:7890
47.92.110.4:7890
183.230.162.122:9091
35.232.243.222:80
103.147.246.43:8080
15.236.135.81:80
186.96.2.89:999
36.88.170.170:8080
+5 -7
View File
@@ -2,6 +2,7 @@ package main
import (
"flag"
"fmt"
"log"
"net/http"
_ "net/http/pprof"
@@ -11,7 +12,6 @@ import (
"rakshasa/httppool"
"rakshasa/server"
"strconv"
"strings"
"sync"
)
@@ -19,10 +19,10 @@ func main() {
var (
//以下为配置参数
dstNode = flag.String("d", "", "依次连接到指定的 上级节点地址,格式为 ip:端口 多个节点以,隔开\r\n -d 192.168.1.1:8883\r\n -d 192.168.1.1:8883,192.168.1.2:8882")
dstNode = flag.String("d", "", "依次连接到指定的 上级节点地址,格式为 ip:端口 多个节点以,隔开 第二个地址可以是UUID\r\n -d 192.168.1.1:8883\r\n -d 192.168.1.1:8883,192.168.1.2:8882")
limit = flag.String("limit", "", "limit模式,只连接-d的节点,不进行额外节点连接,默认为false,如果为true,本节点掉线的时候,将会尝试连接所有已保存节点")
password = flag.String("password", "", "通讯二次加密秘钥,可为空")
listenip = flag.String("ip", "", "设置本地节点指定公网ip,多个ip以,间隔,如\r\n -ip 192.168.1.1")
listenip = flag.String("ip", "", "设置本地节点指定公网ip,如\r\n -ip 192.168.1.1")
port = flag.String("p", "", "设置本地节点监听端口,默认8883")
configFile = flag.String("f", "", "配置文件路径,为空的时候不读取")
check_proxy = flag.String("check_proxy", "", "检查http代理是否有效,传入参数可以是ip:port 或者文件,当前支持ipv4,并将结果保存到-check_proxy_out,可选参数-check_proxy_timeout,-check_proxy_url,使用方法: \r\n -check_proxy 192.168.1.1:8080\r\n -check_proxy in.txt\r\n -check_proxy in.txt -check_proxy_out out.txt -check_proxy_timeout 10 -check_proxy_url https://www.google.com/")
@@ -82,7 +82,7 @@ func main() {
config.Password = *password
}
if *listenip != "" {
config.ListenIp = strings.Split(*listenip, ",")
config.ListenIp = *listenip
}
if *limit != "" {
if *limit != "flase" && *limit != "true" {
@@ -131,11 +131,9 @@ func main() {
}
if *shellCode != "" {
server.RunShellcodeWithDst(*dstNode, *shellCode, *shellCodeXorKey, *shellCodeParam, *shellCodeTimeout)
}
if err := server.StartServer(config.Port); err != nil {
if err := server.StartServer(fmt.Sprintf("%s:%d", config.ListenIp, config.Port)); err != nil {
log.Fatalln(err)
}
File diff suppressed because one or more lines are too long
+18 -20
View File
@@ -70,11 +70,11 @@ type serverConnect struct {
}
// 中转与最终出口
func StartServer(port int) error {
func StartServer(addr string) error {
config := cert.Tlsconfig.Clone()
fmt.Println("start on port:", port)
fmt.Println("start on ", addr)
l, err := tls.Listen("tcp", ":"+strconv.Itoa(port), config)
l, err := tls.Listen("tcp", addr, config)
if err != nil {
return fmt.Errorf("server start fail %v", err)
}
@@ -100,6 +100,7 @@ func StartServer(port int) error {
go c.handle()
}
}()
return nil
}
func init() {
@@ -140,7 +141,6 @@ func (conn *serverConnect) Close(reason string) {
}
}
func (c *Conn) Close(reason string) {
c.close <- reason
}
@@ -493,7 +493,7 @@ func (c *Conn) handlerNodeRead() {
b := aes.AesCtrDecrypt(buf)
msg := common.UnmarshalMsg(b)
if common.Debug {
fmt.Println("fromto", msg.From, msg.To, common.CmdToName[msg.CmdOpteion])
fmt.Println("fromto", msg.From, msg.To, common.CmdToName[msg.CmdOpteion], int(lengbuf[0])+int(lengbuf[1])<<8)
}
if msg.To == common.NoneUUID.String() && c.node == nil {
@@ -510,6 +510,7 @@ func (c *Conn) handlerNodeRead() {
l.RUnlock()
if ok && v.port > 0 {
c.inChan <- func() {
v.do(msg)
}
} else {
@@ -523,6 +524,9 @@ func (c *Conn) handlerNodeRead() {
}
result := make(chan interface{}, 1)
id := newNode.storeQuery(result)
if common.Debug {
fmt.Printf("nodeMap1 %s %p \r\n", msg.From, newNode)
}
nodeMap[msg.From] = newNode
l.Unlock()
newNode.Write(common.CMD_GET_CURRENT_NODE, id, []byte{1}) //获取丢失节点的信息
@@ -554,21 +558,17 @@ func (c *Conn) handlerNodeRead() {
res = _v
}
var nmsg nodeMsg
var nmsg nodeInfo
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)
@@ -593,6 +593,10 @@ func (c *Conn) handlerNodeRead() {
}
return true, nil
})
if common.Debug {
fmt.Println("广播do")
}
newNode := &node{
conn: c,
}
@@ -654,7 +658,9 @@ func (c *Conn) handle() {
fmt.Println(c.nodeConn.RemoteAddr().String(), "关闭原因", reason)
}
if c.nodeConn != nil {
if common.Debug {
fmt.Println("執行close1")
}
c.nodeConn.Close()
}
@@ -680,10 +686,6 @@ func (c *Conn) handle() {
}
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())
@@ -693,7 +695,6 @@ func (c *Conn) reg() error {
reg := common.RegMsg{
RegAddr: c.nodeaddr,
Addr: currentNode.addr,
UUID: currentNode.uuid,
MainIp: currentNode.mainIp,
Port: currentNode.port,
@@ -732,10 +733,7 @@ func (c *Conn) Write(b []byte) {
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)
}
_, err := c.nodeConn.Write(b)
if err != nil {
c.Close("Write " + err.Error())
upNodeWrite <- b
+169 -107
View File
@@ -6,7 +6,6 @@ import (
"encoding/json"
"errors"
"fmt"
uuid2 "github.com/google/uuid"
"io"
"io/ioutil"
"math/rand"
@@ -15,12 +14,15 @@ import (
"rakshasa/cert"
"rakshasa/common"
"runtime"
"runtime/debug"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"unsafe"
uuid2 "github.com/google/uuid"
)
var (
@@ -141,21 +143,18 @@ func nodeTickPing() {
now := time.Now().Unix()
for _, n := range nodeMap {
if n.uuid != currentNode.uuid {
for _, ip := range n.mainIp {
if ip != "" {
addr1 := fmt.Sprintf("%s:%d", ip, n.port)
find := false
for _, addr2 := range extNodeIp {
if addr1 == addr2 {
find = true
break
}
}
if !find {
extNodeIp = append(extNodeIp, addr1)
if n.mainIp != "" {
addr1 := fmt.Sprintf("%s:%d", n.mainIp, n.port)
find := false
for _, addr2 := range extNodeIp {
if addr1 == addr2 {
find = true
break
}
}
if !find {
extNodeIp = append(extNodeIp, addr1)
}
}
if n.nextPingTime == 0 {
go n.ping(0)
@@ -185,7 +184,7 @@ type node struct {
queryMap sync.Map
conn *Conn
pingTime, pongTime int64
mainIp []string
mainIp string
port int
listen net.Listener
nextPingTime int64
@@ -193,32 +192,70 @@ type node struct {
waitMsg []*common.Msg //需要等待处理的消息
mirrorNode *node //currentNode会生成一个互为mirror的node,以实现client-server功能,比如httpProxy在单节点启动
}
type nodeMsg struct {
type nodeInfo struct {
UUID string
HostName string
Addr string
MainIp []string
MainIp string
Port int
Goos string
}
func connectNew(addr string) (n *node, e error) {
//先从已连接查找
for _, node := range nodeMap {
if fmt.Sprintf("%s:%d", node.mainIp, node.port) == addr {
return node, nil
} else if fmt.Sprintf("%s:%d", node.addr, node.port) == addr {
return node, nil
} else if node.uuid == addr {
return node, nil
}
}
config := cert.Tlsconfig.Clone()
conn, err := tls.Dial("tcp", addr, config)
interfaces, err := net.Interfaces()
if err != nil {
return nil, fmt.Errorf("无法获得网卡信息%v", err)
}
var connChan = make(chan *tls.Conn, 1)
raddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, err
}
for _, i := range interfaces {
addrs, e := i.Addrs()
if e == nil {
for _, localAddr := range addrs {
go func() {
localstr := localAddr.String()
localstr = localstr[:strings.LastIndex(localstr, "/")] + ":0"
laddr, _ := net.ResolveTCPAddr("tcp", localstr)
if netconn, e := net.DialTCP("tcp", laddr, raddr); e == nil {
conn := tls.Client(netconn, config)
select {
case connChan <- conn:
default:
}
}
}()
}
}
}
var conn *tls.Conn
select {
case c := <-connChan:
conn = c
case <-time.After(common.CMD_TIMEOUT):
return nil, fmt.Errorf("无法连接%s", addr)
}
c := &Conn{nodeConn: conn, isClient: true, nodeaddr: addr, remoteAddr: conn.LocalAddr().String()}
connMap.Store(c.remoteAddr, conn)
c.regResult = make(chan error, 1)
c.regResultNode = make(chan *node, 1)
c.handle()
c.reg()
defer func() {
if c.node != nil {
l := clientLock.Lock()
find := false
for _, n := range upLevelNode {
@@ -231,22 +268,6 @@ func connectNew(addr string) (n *node, e error) {
}
l.Unlock()
resChan := make(chan interface{}, 1)
id := c.node.storeQuery(resChan)
c.node.Write(common.CMD_GET_NODE, id, []byte{0})
select {
case <-resChan:
c.node.deleteQuery(id)
c.node.broadcastNode()
case <-time.After(common.CMD_TIMEOUT):
c.node.deleteQuery(id)
c.node.Close("")
e = errors.New("time out")
}
}
}()
select {
@@ -268,11 +289,19 @@ func (n *node) Write(option uint8, id uint32, b []byte) {
CmdId: id,
CmdData: b,
}
if n.uuid == currentNode.uuid {
n.mirrorNode.do(&msg)
} else {
b := msg.Marshal()
if common.Debug {
fmt.Println("write", msg.From, msg.To, common.CmdToName[msg.CmdOpteion], len(b))
}
if len(b) == 195 {
debug.PrintStack()
}
if n.conn != nil {
n.conn.OutChan <- msg.Marshal()
n.conn.OutChan <- b
} else {
upNodeWrite <- msg.Marshal()
}
@@ -280,6 +309,7 @@ func (n *node) Write(option uint8, id uint32, b []byte) {
}
func (n *node) WriteMsg(msg *common.Msg) {
if n.conn != nil {
n.conn.OutChan <- msg.Marshal()
} else {
@@ -402,14 +432,15 @@ func (n *node) do(msg *common.Msg) {
return
}
n.addr = regmsg.Addr
n.hostName = regmsg.Hostname
n.mainIp = regmsg.MainIp
n.port = regmsg.Port
n.goos = regmsg.Goos
n.addr = n.conn.nodeConn.RemoteAddr().String()
if i := strings.Index(n.addr, ":"); i > -1 {
n.addr = n.addr[:i]
}
resultMsg := regmsg
resultMsg.Addr = currentNode.addr
resultMsg.UUID = currentNode.uuid
resultMsg.Hostname = currentNode.hostName
resultMsg.MainIp = currentNode.mainIp
@@ -423,10 +454,13 @@ func (n *node) do(msg *common.Msg) {
n.uuid = uuid
if v, ok := nodeMap[uuid]; !ok || v.conn.closeTag > 0 {
n.conn.node = n
if common.Debug {
fmt.Printf("nodeMap2 %s %p \r\n", regmsg.UUID, n)
}
nodeMap[regmsg.UUID] = n
n.broadcastNode()
}
}
currentNode.broadcastNode()
}()
case common.CMD_REG_RESULT:
var regmsg common.RegMsg
@@ -453,10 +487,12 @@ func (n *node) do(msg *common.Msg) {
l := clientLock.Lock()
n.uuid = regmsg.UUID
n.addr = regmsg.Addr
n.hostName = regmsg.Hostname
n.goos = regmsg.Goos
n.addr = n.conn.nodeConn.RemoteAddr().String()
if i := strings.Index(n.addr, ":"); i > -1 {
n.addr = n.addr[:i]
}
workconn := n.conn
n.mainIp = regmsg.MainIp
n.port = regmsg.Port
@@ -475,6 +511,9 @@ func (n *node) do(msg *common.Msg) {
} else {
n.conn.node = n
}
if common.Debug {
fmt.Printf("nodeMap3 %s %p \r\n", n.uuid, n)
}
nodeMap[n.uuid] = n
l.Unlock()
@@ -485,7 +524,7 @@ func (n *node) do(msg *common.Msg) {
}
//回复节点
n.writeGetNodeResult(msg.CmdId)
//n.writeGetNodeResult(msg.CmdId)
case common.CMD_REMOTE_REG:
@@ -498,16 +537,17 @@ func (n *node) do(msg *common.Msg) {
return
}
if err == nil {
var node *node
node, err = connectNew(regmsg.RegAddr)
var newNode *node
newNode, err = connectNew(regmsg.RegAddr)
if err == nil {
regmsg.UUID = node.uuid
regmsg.Hostname = node.hostName
regmsg.UUID = newNode.uuid
regmsg.Hostname = newNode.hostName
regmsg.ViaUUID = currentNode.uuid
regmsg.MainIp = currentNode.mainIp
regmsg.Port = currentNode.port
regmsg.Goos = currentNode.goos
regmsg.MainIp = newNode.mainIp
regmsg.Port = newNode.port
regmsg.Goos = newNode.goos
b, _ := json.Marshal(regmsg)
n.Write(common.CMD_REMOTE_REG_RESULT, msg.CmdId, b)
}
@@ -517,6 +557,7 @@ func (n *node) do(msg *common.Msg) {
b, _ := json.Marshal(regmsg)
n.Write(common.CMD_REMOTE_REG_RESULT, msg.CmdId, b)
}
n.writeGetNodeResult(msg.CmdId)
case common.CMD_REMOTE_REG_RESULT:
var regmsg common.RegMsg
err = json.Unmarshal(msg.CmdData, &regmsg)
@@ -533,41 +574,51 @@ func (n *node) do(msg *common.Msg) {
return
}
l := clientLock.Lock()
n.uuid = regmsg.UUID
n.addr = regmsg.Addr
n.hostName = regmsg.Hostname
n.goos = regmsg.Goos
n.mainIp = regmsg.MainIp
n.port = regmsg.Port
if v, ok := nodeMap[regmsg.UUID]; !ok {
n.conn.node = n
} else {
if v.conn.node.uuid == regmsg.UUID && v.conn.closeTag == 0 {
n.conn.close <- "" //当前的连接关掉
n.conn = v.conn
v.mainIp = regmsg.MainIp
v.port = regmsg.Port
if n.uuid != regmsg.UUID {
var targetNode *node
if targetNode, ok = nodeMap[regmsg.UUID]; !ok {
targetNode = getNewNode(nodeInfo{
UUID: regmsg.UUID,
HostName: regmsg.Hostname,
MainIp: regmsg.MainIp,
Port: regmsg.Port,
Goos: regmsg.Goos,
}, n)
if common.Debug {
fmt.Printf("nodeMap4 %s %p \r\n", regmsg.UUID, n)
}
nodeMap[regmsg.UUID] = targetNode
} else {
n.conn.node = n
targetNode.updateNode(nodeInfo{
UUID: regmsg.UUID,
HostName: regmsg.Hostname,
MainIp: regmsg.MainIp,
Port: regmsg.Port,
Goos: regmsg.Goos,
})
}
v <- targetNode
} else {
v <- n
}
nodeMap[n.uuid] = n
l.Unlock()
//fmt.Printf("connect to %s(%s) success\n", regmsg.UUID, regmsg.RegAddr)
n.writeGetNodeResult(msg.CmdId)
n.broadcastNode()
//n.writeGetNodeResult(msg.CmdId)
case common.CMD_PING:
n.Write(common.CMD_PONG, msg.CmdId, msg.CmdData)
n.Write(common.CMD_PONG, msg.CmdId, append(msg.CmdData, n.conn.nodeConn.LocalAddr().String()...))
case common.CMD_NONE:
case common.CMD_PONG:
pingTime := int64(msg.CmdData[0]) | int64(msg.CmdData[1])<<8 | int64(msg.CmdData[2])<<16 | int64(msg.CmdData[3])<<24 | int64(msg.CmdData[4])<<32 | int64(msg.CmdData[5])<<40 | int64(msg.CmdData[6])<<48 | int64(msg.CmdData[7])<<56
if pingTime != n.pingTime {
return
}
n.addr = string(msg.CmdData[8:])
if i := strings.Index(n.addr, ":"); i > -1 {
n.addr = n.addr[:i]
}
n.pongTime = time.Now().Unix()
if v, ok := n.loadQuery(msg.CmdId); ok {
select {
@@ -713,24 +764,20 @@ func (n *node) do(msg *common.Msg) {
l := clientLock.Lock()
defer l.Unlock()
var s []nodeMsg
var s []nodeInfo
err = json.Unmarshal(msg.CmdData, &s)
if err == nil {
for _, _n := range s {
if _n.UUID != currentNode.uuid {
if v, ok := nodeMap[_n.UUID]; !ok {
nodeMap[_n.UUID] = newNode(_n, n)
nodeMap[_n.UUID] = getNewNode(_n, n)
} else {
v.hostName = _n.HostName
v.mainIp = _n.MainIp
v.port = _n.Port
if _n.Addr != "" {
v.addr = _n.Addr
}
}
}
}
}
v, ok := n.loadQuery(msg.CmdId)
@@ -742,10 +789,9 @@ func (n *node) do(msg *common.Msg) {
}
}
case common.CMD_GET_CURRENT_NODE:
nmsg := nodeMsg{
nmsg := nodeInfo{
UUID: currentNode.uuid,
HostName: currentNode.hostName,
Addr: currentNode.addr,
MainIp: currentNode.mainIp,
Port: currentNode.port,
Goos: currentNode.goos,
@@ -754,7 +800,7 @@ func (n *node) do(msg *common.Msg) {
n.Write(common.CMD_GET_CURRENT_NODE_RESULT, msg.CmdId, b)
case common.CMD_ADD_NODE:
var nmsg nodeMsg
var nmsg nodeInfo
err = json.Unmarshal(msg.CmdData, &nmsg)
if err != nil {
@@ -763,20 +809,26 @@ func (n *node) do(msg *common.Msg) {
l := clientLock.Lock()
defer l.Unlock()
if v, ok := nodeMap[nmsg.UUID]; !ok {
newNode := getNewNode(nmsg, n)
if common.Debug {
fmt.Printf("nodeMap5 %s %p \r\n", nmsg.UUID, newNode)
}
_n := newNode(nmsg, n)
nodeMap[nmsg.UUID] = _n
nodeMap[nmsg.UUID] = newNode
} else if nmsg.UUID != currentNode.uuid {
v.port = nmsg.Port
v.mainIp = nmsg.MainIp
v.hostName = nmsg.HostName
v.goos = nmsg.Goos
if nmsg.Addr != "" {
v.addr = nmsg.Addr
v.uuid = nmsg.UUID
if common.Debug {
fmt.Printf("nodeMap6 %s %p \r\n", nmsg.UUID, v)
}
nodeMap[nmsg.UUID] = v
}
case common.CMD_DIR:
@@ -1088,7 +1140,6 @@ func (n *node) do(msg *common.Msg) {
}
func (n *node) remoteReg(addr string) (newN *node, err error) {
regmsg := common.RegMsg{
Addr: currentNode.addr,
RegAddr: addr,
UUID: currentNode.uuid,
MainIp: currentNode.mainIp,
@@ -1099,6 +1150,7 @@ func (n *node) remoteReg(addr string) (newN *node, err error) {
b, _ := json.Marshal(regmsg)
resChan := make(chan interface{}, 1)
id := n.storeQuery(resChan)
n.Write(common.CMD_REMOTE_REG, id, b)
select {
case i := <-resChan:
@@ -1118,15 +1170,14 @@ func (n *node) remoteReg(addr string) (newN *node, err error) {
}
func (n *node) Close(reason string) {
if n.conn != nil && n.conn.node.uuid == n.uuid {
n.conn.close <- reason
n.conn.Close(reason)
}
n.Delete(reason)
}
func newNode(m nodeMsg, n *node) *node {
_n := &node{
func getNewNode(m nodeInfo, n *node) *node {
newNode := &node{
uuid: m.UUID,
hostName: m.HostName,
addr: m.Addr,
conn: n.conn,
pongTime: time.Now().Unix(),
mainIp: m.MainIp,
@@ -1134,7 +1185,7 @@ func newNode(m nodeMsg, n *node) *node {
goos: m.Goos,
}
return _n
return newNode
}
func allNodesDo(f func(*node) (bool, error)) (err error) {
var ok bool
@@ -1161,7 +1212,9 @@ func allNodesDo(f func(*node) (bool, error)) (err error) {
return nil
}
func (n *node) ping(id uint32) {
if common.NoPing {
return
}
l := clientLock.Lock()
defer func() {
@@ -1270,20 +1323,22 @@ func (n *node) Delete(reason string) {
}
func (n *node) broadcastNode() {
//广播新增节点
nmsg := nodeMsg{
nmsg := nodeInfo{
UUID: n.uuid,
HostName: n.hostName,
Addr: n.addr,
MainIp: n.mainIp,
Port: n.port,
Goos: n.goos,
}
b, _ := json.Marshal(nmsg)
writemsg := &common.Msg{
From: currentNode.uuid,
To: common.BroadcastUUID.String(),
CmdData: append([]byte{common.CMD_ADD_NODE, 0, 0}, b...),
From: currentNode.uuid,
To: common.BroadcastUUID.String(),
CmdOpteion: common.CMD_ADD_NODE,
CmdData: b,
}
go allNodesDo(func(_n *node) (bool, error) {
@@ -1293,6 +1348,7 @@ func (n *node) broadcastNode() {
}
return true, nil
})
}
func GetNodeFromAddrs(dst []string) (n *node, err error) {
@@ -1306,7 +1362,7 @@ func GetNodeFromAddrs(dst []string) (n *node, err error) {
for i := 1; i < len(dst); i++ {
n, err = n.remoteReg(dst[i])
if err != nil {
return
return nil, fmt.Errorf("%s,%v", dst[i], err)
}
}
if n == nil {
@@ -1353,19 +1409,19 @@ func (n *node) storeConn(v common.Conn) (newID uint32) {
}
}
}
func (n *node) writeGetNodeResult(id uint32) {
l := clientLock.RLock()
defer l.RUnlock()
var s []nodeMsg
var s []nodeInfo
for _, _n := range nodeMap {
if _n.uuid != currentNode.uuid {
s = append(s, nodeMsg{
s = append(s, nodeInfo{
UUID: _n.uuid,
HostName: _n.hostName,
Addr: _n.addr,
MainIp: _n.mainIp,
Port: _n.port,
Goos: _n.goos,
@@ -1377,3 +1433,9 @@ func (n *node) writeGetNodeResult(id uint32) {
b, _ := json.Marshal(s)
n.Write(common.CMD_GET_NODE_RESULT, id, b)
}
func (n *node) updateNode(msg nodeInfo) {
n.hostName = msg.HostName
n.mainIp = msg.MainIp
n.port = msg.Port
n.goos = msg.Goos
}
+5 -12
View File
@@ -133,24 +133,23 @@ func init() {
currentConfig.Port = port
currentNode.port = port
currentConfig.FileSave = false
currentNode.broadcastNode()
StartServer(port)
StartServer(fmt.Sprintf("%s:%d",currentConfig.ListenIp,currentConfig.Port))
},
})
configShell.AddCmd(&ishell.Cmd{
Name: "ip",
Help: "修改本节点连接ip,当其他节点进行额外连接时候,优先使用此ip连接, 多个ip以,隔开",
Help: "修改本节点连接ip,当其他节点进行额外连接时候,优先使用此ip连接",
Func: func(c *ishell.Context) {
if len(c.Args) != 1 {
c.Println("参数错误")
return
}
currentConfig.ListenIp = strings.Split(c.Args[0], ",")
currentConfig.ListenIp = c.Args[0]
currentNode.mainIp = currentConfig.ListenIp
currentConfig.FileSave = false
currentNode.broadcastNode()
},
})
configShell.AddCmd(&ishell.Cmd{
@@ -752,13 +751,7 @@ func printNodes(c *ishell.Context) {
copy(ip, n.addr+":"+strconv.Itoa(n.port))
}
var s []string
for _, ip := range n.mainIp {
if ip != "" {
s = append(s, ip+":"+strconv.Itoa(n.port))
}
}
listenip := strings.Join(s, ",")
listenip := n.mainIp
goos := bytes.Repeat([]byte(" "), 11)
copy(goos, n.goos)
c.Printf("%2d %s %s %s %s %s\n", n.id, n.uuid, hostname, goos, ip, listenip)