Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77bfa45172 | ||
|
|
3616768682 | ||
|
|
f015b828fc | ||
|
|
df1e16e708 | ||
|
|
c68094cc12 | ||
|
|
a0df0b1e95 |
+2
-1
@@ -20,4 +20,5 @@ wintun.dll
|
|||||||
.vscode/
|
.vscode/
|
||||||
app/.idea/
|
app/.idea/
|
||||||
*_debug_bin*
|
*_debug_bin*
|
||||||
cmd/openp2p
|
cmd/openp2p
|
||||||
|
vendor/
|
||||||
+2
-2
@@ -31,7 +31,7 @@ P2P直连可以让你的设备跑满带宽。不论你的设备在任何网络
|
|||||||
## 快速入门
|
## 快速入门
|
||||||
仅需简单4步就能用起来。
|
仅需简单4步就能用起来。
|
||||||
下面是一个远程办公例子:在家里连入办公室Windows电脑。
|
下面是一个远程办公例子:在家里连入办公室Windows电脑。
|
||||||
(另外一个快速入门视频 https://www.bilibili.com/video/BV1Et4y1P7bF/)
|
(另外一个快速入门视频 <https://www.bilibili.com/video/BV1Et4y1P7bF/>)
|
||||||
### 1.注册
|
### 1.注册
|
||||||
前往<https://console.openp2p.cn> 注册新用户,暂无需任何认证
|
前往<https://console.openp2p.cn> 注册新用户,暂无需任何认证
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ Windows默认会阻止没有花钱买它家证书签名过的程序,选择“
|
|||||||
服务端有个调度模型,根据带宽、ping值、稳定性、服务时长,尽可能地使共享节点均匀地提供服务。连接共享节点使用TOTP密码,hmac-sha256算法校验,它是一次性密码,和我们平时使用的手机验证码或银行密码器一样的原理。
|
服务端有个调度模型,根据带宽、ping值、稳定性、服务时长,尽可能地使共享节点均匀地提供服务。连接共享节点使用TOTP密码,hmac-sha256算法校验,它是一次性密码,和我们平时使用的手机验证码或银行密码器一样的原理。
|
||||||
|
|
||||||
## 编译
|
## 编译
|
||||||
go version go1.18.1+
|
go version 1.20 only (支持win7)
|
||||||
cd到代码根目录,执行
|
cd到代码根目录,执行
|
||||||
```
|
```
|
||||||
make
|
make
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ That's right, the relay node is naturally an man-in-middle, so AES encryption is
|
|||||||
The server side has a scheduling model, which calculate bandwith, ping value,stability and service duration to provide a well-proportioned service to every share node. It uses TOTP(Time-based One-time Password) with hmac-sha256 algorithem, its theory as same as the cellphone validation code or bank cipher coder.
|
The server side has a scheduling model, which calculate bandwith, ping value,stability and service duration to provide a well-proportioned service to every share node. It uses TOTP(Time-based One-time Password) with hmac-sha256 algorithem, its theory as same as the cellphone validation code or bank cipher coder.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
go version go1.18.1+
|
go version 1.20 only (support win7)
|
||||||
cd root directory of the socure code and execute
|
cd root directory of the socure code and execute
|
||||||
```
|
```
|
||||||
make
|
make
|
||||||
|
|||||||
+3
-2
@@ -2,9 +2,10 @@
|
|||||||
depends on openjdk 11, gradle 8.1.3, ndk 21
|
depends on openjdk 11, gradle 8.1.3, ndk 21
|
||||||
```
|
```
|
||||||
|
|
||||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
# latest version not support go1.20
|
||||||
|
go install golang.org/x/mobile/cmd/gomobile@7c4916698cc93475ebfea76748ee0faba2deb2a5
|
||||||
gomobile init
|
gomobile init
|
||||||
go get -v golang.org/x/mobile/bind
|
go get -v golang.org/x/mobile/bind@7c4916698cc93475ebfea76748ee0faba2deb2a5
|
||||||
cd core
|
cd core
|
||||||
gomobile bind -target android -v
|
gomobile bind -target android -v
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
|
|||||||
@@ -203,7 +203,8 @@ class OpenP2PService : VpnService() {
|
|||||||
val network = Network(id, name, gateway, nodeList)
|
val network = Network(id, name, gateway, nodeList)
|
||||||
println(network)
|
println(network)
|
||||||
Log.i(OpenP2PService.LOG_TAG, "onBind");
|
Log.i(OpenP2PService.LOG_TAG, "onBind");
|
||||||
builder.addDnsServer("8.8.8.8")
|
builder.addDnsServer("223.5.5.5")
|
||||||
|
builder.addDnsServer("2400:3200::1") // alicloud dns v6 & v4
|
||||||
builder.addRoute("10.2.3.0", 24)
|
builder.addRoute("10.2.3.0", 24)
|
||||||
// builder.addRoute("0.0.0.0", 0);
|
// builder.addRoute("0.0.0.0", 0);
|
||||||
builder.setSession(LOG_TAG!!)
|
builder.setSession(LOG_TAG!!)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package openp2p
|
package openp2p
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -114,3 +115,15 @@ func TestIsIPv6(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNodeID(t *testing.T) {
|
||||||
|
node1 := "n1-stable"
|
||||||
|
node2 := "tony-stable"
|
||||||
|
nodeID1 := NodeNameToID(node1)
|
||||||
|
nodeID2 := NodeNameToID(node2)
|
||||||
|
if nodeID1 < nodeID2 {
|
||||||
|
fmt.Printf("%s < %s\n", node1, node2)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s >= %s\n", node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+20
-18
@@ -78,12 +78,13 @@ type Config struct {
|
|||||||
Apps []*AppConfig `json:"apps"`
|
Apps []*AppConfig `json:"apps"`
|
||||||
|
|
||||||
LogLevel int
|
LogLevel int
|
||||||
|
MaxLogSize int
|
||||||
daemonMode bool
|
daemonMode bool
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
sdwanMtx sync.Mutex
|
sdwanMtx sync.Mutex
|
||||||
sdwan SDWANInfo
|
sdwan SDWANInfo
|
||||||
delNodes []SDWANNode
|
delNodes []*SDWANNode
|
||||||
addNodes []SDWANNode
|
addNodes []*SDWANNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) getSDWAN() SDWANInfo {
|
func (c *Config) getSDWAN() SDWANInfo {
|
||||||
@@ -92,23 +93,30 @@ func (c *Config) getSDWAN() SDWANInfo {
|
|||||||
return c.sdwan
|
return c.sdwan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) getDelNodes() []SDWANNode {
|
func (c *Config) getDelNodes() []*SDWANNode {
|
||||||
c.sdwanMtx.Lock()
|
c.sdwanMtx.Lock()
|
||||||
defer c.sdwanMtx.Unlock()
|
defer c.sdwanMtx.Unlock()
|
||||||
return c.delNodes
|
return c.delNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) getAddNodes() []SDWANNode {
|
func (c *Config) getAddNodes() []*SDWANNode {
|
||||||
c.sdwanMtx.Lock()
|
c.sdwanMtx.Lock()
|
||||||
defer c.sdwanMtx.Unlock()
|
defer c.sdwanMtx.Unlock()
|
||||||
return c.addNodes
|
return c.addNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) resetSDWAN() {
|
||||||
|
c.sdwanMtx.Lock()
|
||||||
|
defer c.sdwanMtx.Unlock()
|
||||||
|
c.delNodes = []*SDWANNode{}
|
||||||
|
c.addNodes = []*SDWANNode{}
|
||||||
|
c.sdwan = SDWANInfo{}
|
||||||
|
}
|
||||||
func (c *Config) setSDWAN(s SDWANInfo) {
|
func (c *Config) setSDWAN(s SDWANInfo) {
|
||||||
c.sdwanMtx.Lock()
|
c.sdwanMtx.Lock()
|
||||||
defer c.sdwanMtx.Unlock()
|
defer c.sdwanMtx.Unlock()
|
||||||
// get old-new
|
// get old-new
|
||||||
c.delNodes = []SDWANNode{}
|
c.delNodes = []*SDWANNode{}
|
||||||
for _, oldNode := range c.sdwan.Nodes {
|
for _, oldNode := range c.sdwan.Nodes {
|
||||||
isDeleted := true
|
isDeleted := true
|
||||||
for _, newNode := range s.Nodes {
|
for _, newNode := range s.Nodes {
|
||||||
@@ -122,7 +130,7 @@ func (c *Config) setSDWAN(s SDWANInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// get new-old
|
// get new-old
|
||||||
c.addNodes = []SDWANNode{}
|
c.addNodes = []*SDWANNode{}
|
||||||
for _, newNode := range s.Nodes {
|
for _, newNode := range s.Nodes {
|
||||||
isNew := true
|
isNew := true
|
||||||
for _, oldNode := range c.sdwan.Nodes {
|
for _, oldNode := range c.sdwan.Nodes {
|
||||||
@@ -230,17 +238,8 @@ func (c *Config) delete(app AppConfig) {
|
|||||||
defer c.mtx.Unlock()
|
defer c.mtx.Unlock()
|
||||||
defer c.save()
|
defer c.save()
|
||||||
for i := 0; i < len(c.Apps); i++ {
|
for i := 0; i < len(c.Apps); i++ {
|
||||||
got := false
|
if (app.SrcPort != 0 && c.Apps[i].Protocol == app.Protocol && c.Apps[i].SrcPort == app.SrcPort) || // normal app
|
||||||
if app.SrcPort != 0 { // normal p2papp
|
(app.SrcPort == 0 && c.Apps[i].SrcPort == 0 && c.Apps[i].PeerNode == app.PeerNode) { // memapp
|
||||||
if c.Apps[i].Protocol == app.Protocol && c.Apps[i].SrcPort == app.SrcPort {
|
|
||||||
got = true
|
|
||||||
}
|
|
||||||
} else { // memapp
|
|
||||||
if c.Apps[i].PeerNode == app.PeerNode {
|
|
||||||
got = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if got {
|
|
||||||
if i == len(c.Apps)-1 {
|
if i == len(c.Apps)-1 {
|
||||||
c.Apps = c.Apps[:i]
|
c.Apps = c.Apps[:i]
|
||||||
} else {
|
} else {
|
||||||
@@ -249,7 +248,6 @@ func (c *Config) delete(app AppConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) save() {
|
func (c *Config) save() {
|
||||||
@@ -280,6 +278,7 @@ func (c *Config) saveCache() {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gConf.LogLevel = int(LvINFO)
|
gConf.LogLevel = int(LvINFO)
|
||||||
|
gConf.MaxLogSize = 1024 * 1024
|
||||||
gConf.Network.ShareBandwidth = 10
|
gConf.Network.ShareBandwidth = 10
|
||||||
gConf.Network.ServerHost = "api.openp2p.cn"
|
gConf.Network.ServerHost = "api.openp2p.cn"
|
||||||
gConf.Network.ServerPort = WsPort
|
gConf.Network.ServerPort = WsPort
|
||||||
@@ -463,6 +462,9 @@ func parseParams(subCommand string, cmd string) {
|
|||||||
if f.Name == "loglevel" {
|
if f.Name == "loglevel" {
|
||||||
gConf.LogLevel = *logLevel
|
gConf.LogLevel = *logLevel
|
||||||
}
|
}
|
||||||
|
if f.Name == "maxlogsize" {
|
||||||
|
gConf.MaxLogSize = *maxLogSize
|
||||||
|
}
|
||||||
if f.Name == "tcpport" {
|
if f.Name == "tcpport" {
|
||||||
gConf.Network.TCPPort = *tcpPort
|
gConf.Network.TCPPort = *tcpPort
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -13,12 +13,12 @@ import (
|
|||||||
func handshakeC2C(t *P2PTunnel) (err error) {
|
func handshakeC2C(t *P2PTunnel) (err error) {
|
||||||
gLog.Printf(LvDEBUG, "handshakeC2C %s:%d:%d to %s:%d", gConf.Network.Node, t.coneLocalPort, t.coneNatPort, t.config.peerIP, t.config.peerConeNatPort)
|
gLog.Printf(LvDEBUG, "handshakeC2C %s:%d:%d to %s:%d", gConf.Network.Node, t.coneLocalPort, t.coneNatPort, t.config.peerIP, t.config.peerConeNatPort)
|
||||||
defer gLog.Printf(LvDEBUG, "handshakeC2C end")
|
defer gLog.Printf(LvDEBUG, "handshakeC2C end")
|
||||||
conn, err := net.ListenUDP("udp", t.la)
|
conn, err := net.ListenUDP("udp", t.localHoleAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
_, err = UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id})
|
_, err = UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshake error:", err)
|
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshake error:", err)
|
||||||
return err
|
return err
|
||||||
@@ -28,7 +28,7 @@ func handshakeC2C(t *P2PTunnel) (err error) {
|
|||||||
gLog.Println(LvDEBUG, "handshakeC2C read MsgPunchHandshake error:", err)
|
gLog.Println(LvDEBUG, "handshakeC2C read MsgPunchHandshake error:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.ra, _ = net.ResolveUDPAddr("udp", ra.String())
|
t.remoteHoleAddr, _ = net.ResolveUDPAddr("udp", ra.String())
|
||||||
var tunnelID uint64
|
var tunnelID uint64
|
||||||
if len(buff) > openP2PHeaderSize {
|
if len(buff) > openP2PHeaderSize {
|
||||||
req := P2PHandshakeReq{}
|
req := P2PHandshakeReq{}
|
||||||
@@ -40,7 +40,7 @@ func handshakeC2C(t *P2PTunnel) (err error) {
|
|||||||
}
|
}
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
||||||
gLog.Printf(LvDEBUG, "read %d handshake ", t.id)
|
gLog.Printf(LvDEBUG, "read %d handshake ", t.id)
|
||||||
UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
_, head, _, _, err = UDPRead(conn, HandshakeTimeout)
|
_, head, _, _, err = UDPRead(conn, HandshakeTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
|
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
|
||||||
@@ -49,7 +49,7 @@ func handshakeC2C(t *P2PTunnel) (err error) {
|
|||||||
}
|
}
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck && tunnelID == t.id {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck && tunnelID == t.id {
|
||||||
gLog.Printf(LvDEBUG, "read %d handshake ack ", t.id)
|
gLog.Printf(LvDEBUG, "read %d handshake ack ", t.id)
|
||||||
_, err = UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
_, err = UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
|
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
|
||||||
return err
|
return err
|
||||||
@@ -70,7 +70,7 @@ func handshakeC2S(t *P2PTunnel) error {
|
|||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
randPorts := r.Perm(65532)
|
randPorts := r.Perm(65532)
|
||||||
conn, err := net.ListenUDP("udp", t.la)
|
conn, err := net.ListenUDP("udp", t.localHoleAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ func handshakeC2S(t *P2PTunnel) error {
|
|||||||
gLog.Println(LvERROR, "parse p2pheader error:", err)
|
gLog.Println(LvERROR, "parse p2pheader error:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.ra, _ = net.ResolveUDPAddr("udp", dst.String())
|
t.remoteHoleAddr, _ = net.ResolveUDPAddr("udp", dst.String())
|
||||||
var tunnelID uint64
|
var tunnelID uint64
|
||||||
if len(buff) > openP2PHeaderSize {
|
if len(buff) > openP2PHeaderSize {
|
||||||
req := P2PHandshakeReq{}
|
req := P2PHandshakeReq{}
|
||||||
@@ -123,7 +123,7 @@ func handshakeC2S(t *P2PTunnel) error {
|
|||||||
}
|
}
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
||||||
gLog.Printf(LvDEBUG, "handshakeC2S read %d handshake ", t.id)
|
gLog.Printf(LvDEBUG, "handshakeC2S read %d handshake ", t.id)
|
||||||
UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
for {
|
for {
|
||||||
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
|
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -146,8 +146,8 @@ func handshakeC2S(t *P2PTunnel) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck {
|
||||||
gLog.Printf(LvDEBUG, "handshakeC2S read %d handshake ack %s", t.id, t.ra.String())
|
gLog.Printf(LvDEBUG, "handshakeC2S read %d handshake ack %s", t.id, t.remoteHoleAddr.String())
|
||||||
_, err = UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
_, err = UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
gLog.Println(LvDEBUG, "handshakeS2C read msg but not MsgPunchHandshakeAck")
|
gLog.Println(LvDEBUG, "handshakeS2C read msg but not MsgPunchHandshakeAck")
|
||||||
@@ -178,7 +178,7 @@ func handshakeS2C(t *P2PTunnel) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id})
|
UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id})
|
||||||
_, head, buff, _, err := UDPRead(conn, HandshakeTimeout)
|
_, head, buff, _, err := UDPRead(conn, HandshakeTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// gLog.Println(LevelDEBUG, "one of the handshake error:", err)
|
// gLog.Println(LevelDEBUG, "one of the handshake error:", err)
|
||||||
@@ -199,7 +199,7 @@ func handshakeS2C(t *P2PTunnel) error {
|
|||||||
|
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshake && tunnelID == t.id {
|
||||||
gLog.Printf(LvDEBUG, "handshakeS2C read %d handshake ", t.id)
|
gLog.Printf(LvDEBUG, "handshakeS2C read %d handshake ", t.id)
|
||||||
UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
// may read several MsgPunchHandshake
|
// may read several MsgPunchHandshake
|
||||||
for {
|
for {
|
||||||
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
|
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
|
||||||
@@ -224,7 +224,7 @@ func handshakeS2C(t *P2PTunnel) error {
|
|||||||
}
|
}
|
||||||
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck {
|
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck {
|
||||||
gLog.Printf(LvDEBUG, "handshakeS2C read %d handshake ack %s", t.id, conn.LocalAddr().String())
|
gLog.Printf(LvDEBUG, "handshakeS2C read %d handshake ack %s", t.id, conn.LocalAddr().String())
|
||||||
UDPWrite(conn, t.ra, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
UDPWrite(conn, t.remoteHoleAddr, MsgP2P, MsgPunchHandshakeAck, P2PHandshakeReq{ID: t.id})
|
||||||
gotIt = true
|
gotIt = true
|
||||||
la, _ := net.ResolveUDPAddr("udp", conn.LocalAddr().String())
|
la, _ := net.ResolveUDPAddr("udp", conn.LocalAddr().String())
|
||||||
gotCh <- la
|
gotCh <- la
|
||||||
@@ -238,14 +238,14 @@ func handshakeS2C(t *P2PTunnel) error {
|
|||||||
gLog.Printf(LvDEBUG, "send symmetric handshake end")
|
gLog.Printf(LvDEBUG, "send symmetric handshake end")
|
||||||
if compareVersion(t.config.peerVersion, SymmetricSimultaneouslySendVersion) < 0 { // compatible with old client
|
if compareVersion(t.config.peerVersion, SymmetricSimultaneouslySendVersion) < 0 { // compatible with old client
|
||||||
gLog.Println(LvDEBUG, "handshakeS2C ready, notify peer connect")
|
gLog.Println(LvDEBUG, "handshakeS2C ready, notify peer connect")
|
||||||
t.pn.push(t.config.PeerNode, MsgPushHandshakeStart, TunnelMsg{ID: t.id})
|
GNetwork.push(t.config.PeerNode, MsgPushHandshakeStart, TunnelMsg{ID: t.id})
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(HandshakeTimeout):
|
case <-time.After(HandshakeTimeout):
|
||||||
return fmt.Errorf("wait handshake timeout")
|
return fmt.Errorf("wait handshake timeout")
|
||||||
case la := <-gotCh:
|
case la := <-gotCh:
|
||||||
t.la = la
|
t.localHoleAddr = la
|
||||||
gLog.Println(LvDEBUG, "symmetric handshake ok", la)
|
gLog.Println(LvDEBUG, "symmetric handshake ok", la)
|
||||||
gLog.Printf(LvINFO, "handshakeS2C ok. cost %dms", time.Since(startTime)/time.Millisecond)
|
gLog.Printf(LvINFO, "handshakeS2C ok. cost %dms", time.Since(startTime)/time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-5
@@ -66,7 +66,7 @@ func natTest(serverHost string, serverPort int, localPort int) (publicIP string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The connection can write data to the desired address.
|
// The connection can write data to the desired address.
|
||||||
msg, err := newMessage(MsgNATDetect, 0, nil)
|
msg, err := newMessage(MsgNATDetect, MsgNAT, nil)
|
||||||
_, err = conn.WriteTo(msg, dst)
|
_, err = conn.WriteTo(msg, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
@@ -164,17 +164,33 @@ func publicIPTest(publicIP string, echoPort int) (hasPublicIP int, hasUPNPorNATP
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
dst, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", publicIP, echoPort))
|
dst, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", gConf.Network.ServerHost, gConf.Network.ServerPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
conn.WriteTo([]byte("echo"), dst)
|
|
||||||
|
// The connection can write data to the desired address.
|
||||||
|
msg, _ := newMessage(MsgNATDetect, MsgPublicIP, NatDetectReq{EchoPort: echoPort})
|
||||||
|
_, err = conn.WriteTo(msg, dst)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
buf := make([]byte, 1600)
|
buf := make([]byte, 1600)
|
||||||
|
|
||||||
// wait for echo testing
|
// wait for echo testing
|
||||||
conn.SetReadDeadline(time.Now().Add(PublicIPEchoTimeout))
|
conn.SetReadDeadline(time.Now().Add(PublicIPEchoTimeout))
|
||||||
_, _, err = conn.ReadFromUDP(buf)
|
nRead, _, err := conn.ReadFromUDP(buf)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
|
gLog.Println(LvERROR, "PublicIP detect error:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
natRsp := NatDetectRsp{}
|
||||||
|
err = json.Unmarshal(buf[openP2PHeaderSize:nRead], &natRsp)
|
||||||
|
if err != nil {
|
||||||
|
gLog.Println(LvERROR, "PublicIP detect error:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if natRsp.Port == echoPort {
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
gLog.Println(LvDEBUG, "UPNP or NAT-PMP:YES")
|
gLog.Println(LvDEBUG, "UPNP or NAT-PMP:YES")
|
||||||
hasUPNPorNATPMP = 1
|
hasUPNPorNATPMP = 1
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func addRoute(dst, gw, ifname string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func delRoute(dst, gw string) error {
|
func delRoute(dst, gw string) error {
|
||||||
err := exec.Command("route", "delete", dst, gw).Run()
|
err := exec.Command("route", "delete", dst, "-gateway", gw).Run()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func delRoutesByGateway(gateway string) error {
|
func delRoutesByGateway(gateway string) error {
|
||||||
@@ -68,13 +68,14 @@ func delRoutesByGateway(gateway string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fields := strings.Fields(line)
|
fields := strings.Fields(line)
|
||||||
if len(fields) >= 7 && fields[0] == "default" && fields[len(fields)-1] == gateway {
|
if len(fields) >= 2 {
|
||||||
delCmd := exec.Command("route", "delete", "default", gateway)
|
cmd := exec.Command("route", "delete", fields[0], gateway)
|
||||||
err := delCmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
gLog.Printf(LvERROR, "Delete route %s error:%s", fields[0], err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("Delete route ok: %s %s\n", "default", gateway)
|
gLog.Printf(LvINFO, "Delete route ok: %s %s\n", fields[0], gateway)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+3
-2
@@ -124,9 +124,10 @@ func delRoutesByGateway(gateway string) error {
|
|||||||
delCmd := exec.Command("route", "del", "-net", fields[0], "gw", gateway)
|
delCmd := exec.Command("route", "del", "-net", fields[0], "gw", gateway)
|
||||||
err := delCmd.Run()
|
err := delCmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
gLog.Printf(LvERROR, "Delete route %s error:%s", fields[0], err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("Delete route ok: %s %s %s\n", fields[0], fields[1], gateway)
|
gLog.Printf(LvINFO, "Delete route ok: %s %s %s\n", fields[0], fields[1], gateway)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -133,9 +133,10 @@ func delRoutesByGateway(gateway string) error {
|
|||||||
cmd := exec.Command("route", "delete", fields[0], "mask", fields[1], gateway)
|
cmd := exec.Command("route", "delete", fields[0], "mask", fields[1], gateway)
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Delete route error:", err)
|
gLog.Printf(LvERROR, "Delete route %s error:%s", fields[0], err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("Delete route ok: %s %s %s\n", fields[0], fields[1], gateway)
|
gLog.Printf(LvINFO, "Delete route ok: %s %s %s\n", fields[0], fields[1], gateway)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+1
-1
@@ -174,7 +174,7 @@ func (app *p2pApp) buildDirectTunnel() error {
|
|||||||
pn := GNetwork
|
pn := GNetwork
|
||||||
initErr := pn.requestPeerInfo(&app.config)
|
initErr := pn.requestPeerInfo(&app.config)
|
||||||
if initErr != nil {
|
if initErr != nil {
|
||||||
gLog.Printf(LvERROR, "%s init error:%s", app.config.LogPeerNode(), initErr)
|
gLog.Printf(LvERROR, "%s requestPeerInfo error:%s", app.config.LogPeerNode(), initErr)
|
||||||
return initErr
|
return initErr
|
||||||
}
|
}
|
||||||
t, err = pn.addDirectTunnel(app.config, 0)
|
t, err = pn.addDirectTunnel(app.config, 0)
|
||||||
|
|||||||
+3
-2
@@ -115,6 +115,7 @@ func (pn *P2PNetwork) run() {
|
|||||||
pn.write(MsgHeartbeat, 0, "")
|
pn.write(MsgHeartbeat, 0, "")
|
||||||
case <-pn.restartCh:
|
case <-pn.restartCh:
|
||||||
gLog.Printf(LvDEBUG, "got restart channel")
|
gLog.Printf(LvDEBUG, "got restart channel")
|
||||||
|
GNetwork.sdwan.reset()
|
||||||
pn.online = false
|
pn.online = false
|
||||||
pn.wgReconnect.Wait() // wait read/autorunapp goroutine end
|
pn.wgReconnect.Wait() // wait read/autorunapp goroutine end
|
||||||
delay := ClientAPITimeout + time.Duration(rand.Int()%pn.loginMaxDelaySeconds)*time.Second
|
delay := ClientAPITimeout + time.Duration(rand.Int()%pn.loginMaxDelaySeconds)*time.Second
|
||||||
@@ -124,6 +125,7 @@ func (pn *P2PNetwork) run() {
|
|||||||
gLog.Println(LvERROR, "P2PNetwork init error:", err)
|
gLog.Println(LvERROR, "P2PNetwork init error:", err)
|
||||||
}
|
}
|
||||||
gConf.retryAllApp()
|
gConf.retryAllApp()
|
||||||
|
|
||||||
case t := <-pn.tunnelCloseCh:
|
case t := <-pn.tunnelCloseCh:
|
||||||
gLog.Printf(LvDEBUG, "got tunnelCloseCh %s", t.config.LogPeerNode())
|
gLog.Printf(LvDEBUG, "got tunnelCloseCh %s", t.config.LogPeerNode())
|
||||||
pn.apps.Range(func(id, i interface{}) bool {
|
pn.apps.Range(func(id, i interface{}) bool {
|
||||||
@@ -466,7 +468,7 @@ func (pn *P2PNetwork) newTunnel(config AppConfig, tid uint64, isClient bool) (t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = &P2PTunnel{pn: pn,
|
t = &P2PTunnel{
|
||||||
config: config,
|
config: config,
|
||||||
id: tid,
|
id: tid,
|
||||||
writeData: make(chan []byte, WriteDataChanSize),
|
writeData: make(chan []byte, WriteDataChanSize),
|
||||||
@@ -533,7 +535,6 @@ func (pn *P2PNetwork) init() error {
|
|||||||
caCertPool, errCert := x509.SystemCertPool()
|
caCertPool, errCert := x509.SystemCertPool()
|
||||||
if errCert != nil {
|
if errCert != nil {
|
||||||
gLog.Println(LvERROR, "Failed to load system root CAs:", errCert)
|
gLog.Println(LvERROR, "Failed to load system root CAs:", errCert)
|
||||||
} else {
|
|
||||||
caCertPool = x509.NewCertPool()
|
caCertPool = x509.NewCertPool()
|
||||||
}
|
}
|
||||||
caCertPool.AppendCertsFromPEM([]byte(rootCA))
|
caCertPool.AppendCertsFromPEM([]byte(rootCA))
|
||||||
|
|||||||
+37
-38
@@ -19,13 +19,12 @@ const WriteDataChanSize int = 3000
|
|||||||
var buildTunnelMtx sync.Mutex
|
var buildTunnelMtx sync.Mutex
|
||||||
|
|
||||||
type P2PTunnel struct {
|
type P2PTunnel struct {
|
||||||
pn *P2PNetwork
|
|
||||||
conn underlay
|
conn underlay
|
||||||
hbTime time.Time
|
hbTime time.Time
|
||||||
hbMtx sync.Mutex
|
hbMtx sync.Mutex
|
||||||
config AppConfig
|
config AppConfig
|
||||||
la *net.UDPAddr // local hole address
|
localHoleAddr *net.UDPAddr // local hole address
|
||||||
ra *net.UDPAddr // remote hole address
|
remoteHoleAddr *net.UDPAddr // remote hole address
|
||||||
overlayConns sync.Map // both TCP and UDP
|
overlayConns sync.Map // both TCP and UDP
|
||||||
id uint64 // client side alloc rand.uint64 = server side
|
id uint64 // client side alloc rand.uint64 = server side
|
||||||
running bool
|
running bool
|
||||||
@@ -58,7 +57,7 @@ func (t *P2PTunnel) initPort() {
|
|||||||
t.coneLocalPort = localPort2
|
t.coneLocalPort = localPort2
|
||||||
t.coneNatPort = natPort
|
t.coneNatPort = natPort
|
||||||
}
|
}
|
||||||
t.la = &net.UDPAddr{IP: net.ParseIP(gConf.Network.localIP), Port: t.coneLocalPort}
|
t.localHoleAddr = &net.UDPAddr{IP: net.ParseIP(gConf.Network.localIP), Port: t.coneLocalPort}
|
||||||
gLog.Printf(LvDEBUG, "prepare punching port %d:%d", t.coneLocalPort, t.coneNatPort)
|
gLog.Printf(LvDEBUG, "prepare punching port %d:%d", t.coneLocalPort, t.coneNatPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +84,8 @@ func (t *P2PTunnel) connect() error {
|
|||||||
if req.Token == 0 { // no relay token
|
if req.Token == 0 { // no relay token
|
||||||
req.Token = gConf.Network.Token
|
req.Token = gConf.Network.Token
|
||||||
}
|
}
|
||||||
t.pn.push(t.config.PeerNode, MsgPushConnectReq, req)
|
GNetwork.push(t.config.PeerNode, MsgPushConnectReq, req)
|
||||||
head, body := t.pn.read(t.config.PeerNode, MsgPush, MsgPushConnectRsp, UnderlayConnectTimeout*3)
|
head, body := GNetwork.read(t.config.PeerNode, MsgPush, MsgPushConnectRsp, UnderlayConnectTimeout*3)
|
||||||
if head == nil {
|
if head == nil {
|
||||||
return errors.New("connect error")
|
return errors.New("connect error")
|
||||||
}
|
}
|
||||||
@@ -161,7 +160,7 @@ func (t *P2PTunnel) checkActive() bool {
|
|||||||
|
|
||||||
// call when user delete tunnel
|
// call when user delete tunnel
|
||||||
func (t *P2PTunnel) close() {
|
func (t *P2PTunnel) close() {
|
||||||
t.pn.NotifyTunnelClose(t)
|
GNetwork.NotifyTunnelClose(t)
|
||||||
if !t.running {
|
if !t.running {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -169,7 +168,7 @@ func (t *P2PTunnel) close() {
|
|||||||
if t.conn != nil {
|
if t.conn != nil {
|
||||||
t.conn.Close()
|
t.conn.Close()
|
||||||
}
|
}
|
||||||
t.pn.allTunnels.Delete(t.id)
|
GNetwork.allTunnels.Delete(t.id)
|
||||||
gLog.Printf(LvINFO, "%d p2ptunnel close %s ", t.id, t.config.LogPeerNode())
|
gLog.Printf(LvINFO, "%d p2ptunnel close %s ", t.id, t.config.LogPeerNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +189,7 @@ func (t *P2PTunnel) start() error {
|
|||||||
func (t *P2PTunnel) handshake() error {
|
func (t *P2PTunnel) handshake() error {
|
||||||
if t.config.peerConeNatPort > 0 { // only peer is cone should prepare t.ra
|
if t.config.peerConeNatPort > 0 { // only peer is cone should prepare t.ra
|
||||||
var err error
|
var err error
|
||||||
t.ra, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", t.config.peerIP, t.config.peerConeNatPort))
|
t.remoteHoleAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", t.config.peerIP, t.config.peerConeNatPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -198,7 +197,7 @@ func (t *P2PTunnel) handshake() error {
|
|||||||
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
||||||
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
||||||
} else {
|
} else {
|
||||||
ts := time.Duration(int64(t.punchTs) + t.pn.dt + t.pn.ddtma*int64(time.Since(t.pn.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
ts := time.Duration(int64(t.punchTs) + GNetwork.dt + GNetwork.ddtma*int64(time.Since(GNetwork.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
||||||
if ts > PunchTsDelay || ts < 0 {
|
if ts > PunchTsDelay || ts < 0 {
|
||||||
ts = PunchTsDelay
|
ts = PunchTsDelay
|
||||||
}
|
}
|
||||||
@@ -267,11 +266,11 @@ func (t *P2PTunnel) connectUnderlayUDP() (c underlay, err error) {
|
|||||||
}
|
}
|
||||||
if t.config.isUnderlayServer == 1 {
|
if t.config.isUnderlayServer == 1 {
|
||||||
time.Sleep(time.Millisecond * 10) // punching udp port will need some times in some env
|
time.Sleep(time.Millisecond * 10) // punching udp port will need some times in some env
|
||||||
go t.pn.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
go GNetwork.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
||||||
if t.config.UnderlayProtocol == "kcp" {
|
if t.config.UnderlayProtocol == "kcp" {
|
||||||
ul, err = listenKCP(t.la.String(), TunnelIdleTimeout)
|
ul, err = listenKCP(t.localHoleAddr.String(), TunnelIdleTimeout)
|
||||||
} else {
|
} else {
|
||||||
ul, err = listenQuic(t.la.String(), TunnelIdleTimeout)
|
ul, err = listenQuic(t.localHoleAddr.String(), TunnelIdleTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -293,24 +292,24 @@ func (t *P2PTunnel) connectUnderlayUDP() (c underlay, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//else
|
//else
|
||||||
conn, errL := net.ListenUDP("udp", t.la)
|
conn, errL := net.ListenUDP("udp", t.localHoleAddr)
|
||||||
if errL != nil {
|
if errL != nil {
|
||||||
time.Sleep(time.Millisecond * 10)
|
time.Sleep(time.Millisecond * 10)
|
||||||
conn, errL = net.ListenUDP("udp", t.la)
|
conn, errL = net.ListenUDP("udp", t.localHoleAddr)
|
||||||
if errL != nil {
|
if errL != nil {
|
||||||
return nil, fmt.Errorf("%s listen error:%s", underlayProtocol, errL)
|
return nil, fmt.Errorf("%s listen error:%s", underlayProtocol, errL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.pn.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
GNetwork.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
||||||
gLog.Printf(LvDEBUG, "%s dial to %s", underlayProtocol, t.ra.String())
|
gLog.Printf(LvDEBUG, "%s dial to %s", underlayProtocol, t.remoteHoleAddr.String())
|
||||||
if t.config.UnderlayProtocol == "kcp" {
|
if t.config.UnderlayProtocol == "kcp" {
|
||||||
ul, errL = dialKCP(conn, t.ra, TunnelIdleTimeout)
|
ul, errL = dialKCP(conn, t.remoteHoleAddr, TunnelIdleTimeout)
|
||||||
} else {
|
} else {
|
||||||
ul, errL = dialQuic(conn, t.ra, TunnelIdleTimeout)
|
ul, errL = dialQuic(conn, t.remoteHoleAddr, TunnelIdleTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errL != nil {
|
if errL != nil {
|
||||||
return nil, fmt.Errorf("%s dial to %s error:%s", underlayProtocol, t.ra.String(), errL)
|
return nil, fmt.Errorf("%s dial to %s error:%s", underlayProtocol, t.remoteHoleAddr.String(), errL)
|
||||||
}
|
}
|
||||||
handshakeBegin := time.Now()
|
handshakeBegin := time.Now()
|
||||||
ul.WriteBytes(MsgP2P, MsgTunnelHandshake, []byte("OpenP2P,hello"))
|
ul.WriteBytes(MsgP2P, MsgTunnelHandshake, []byte("OpenP2P,hello"))
|
||||||
@@ -353,12 +352,12 @@ func (t *P2PTunnel) connectUnderlayTCP() (c underlay, err error) {
|
|||||||
|
|
||||||
// client side
|
// client side
|
||||||
if t.config.linkMode == LinkModeTCP4 {
|
if t.config.linkMode == LinkModeTCP4 {
|
||||||
t.pn.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
GNetwork.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
||||||
} else { //tcp punch should sleep for punch the same time
|
} else { //tcp punch should sleep for punch the same time
|
||||||
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
||||||
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
||||||
} else {
|
} else {
|
||||||
ts := time.Duration(int64(t.punchTs) + t.pn.dt + t.pn.ddtma*int64(time.Since(t.pn.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
ts := time.Duration(int64(t.punchTs) + GNetwork.dt + GNetwork.ddtma*int64(time.Since(GNetwork.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
||||||
if ts > PunchTsDelay || ts < 0 {
|
if ts > PunchTsDelay || ts < 0 {
|
||||||
ts = PunchTsDelay
|
ts = PunchTsDelay
|
||||||
}
|
}
|
||||||
@@ -394,7 +393,7 @@ func (t *P2PTunnel) connectUnderlayTCP() (c underlay, err error) {
|
|||||||
func (t *P2PTunnel) connectUnderlayTCPSymmetric() (c underlay, err error) {
|
func (t *P2PTunnel) connectUnderlayTCPSymmetric() (c underlay, err error) {
|
||||||
gLog.Printf(LvDEBUG, "connectUnderlayTCPSymmetric %s start ", t.config.LogPeerNode())
|
gLog.Printf(LvDEBUG, "connectUnderlayTCPSymmetric %s start ", t.config.LogPeerNode())
|
||||||
defer gLog.Printf(LvDEBUG, "connectUnderlayTCPSymmetric %s end ", t.config.LogPeerNode())
|
defer gLog.Printf(LvDEBUG, "connectUnderlayTCPSymmetric %s end ", t.config.LogPeerNode())
|
||||||
ts := time.Duration(int64(t.punchTs) + t.pn.dt + t.pn.ddtma*int64(time.Since(t.pn.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
ts := time.Duration(int64(t.punchTs) + GNetwork.dt + GNetwork.ddtma*int64(time.Since(GNetwork.hbTime)+PunchTsDelay)/int64(NetworkHeartbeatTime) - time.Now().UnixNano())
|
||||||
if ts > PunchTsDelay || ts < 0 {
|
if ts > PunchTsDelay || ts < 0 {
|
||||||
ts = PunchTsDelay
|
ts = PunchTsDelay
|
||||||
}
|
}
|
||||||
@@ -426,7 +425,7 @@ func (t *P2PTunnel) connectUnderlayTCPSymmetric() (c underlay, err error) {
|
|||||||
}
|
}
|
||||||
_, buff, err := ul.ReadBuffer()
|
_, buff, err := ul.ReadBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Printf(LvERROR, "utcp.ReadBuffer error:", err)
|
gLog.Println(LvDEBUG, "c2s ul.ReadBuffer error:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req := P2PHandshakeReq{}
|
req := P2PHandshakeReq{}
|
||||||
@@ -455,7 +454,7 @@ func (t *P2PTunnel) connectUnderlayTCPSymmetric() (c underlay, err error) {
|
|||||||
|
|
||||||
_, buff, err := ul.ReadBuffer()
|
_, buff, err := ul.ReadBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Printf(LvERROR, "utcp.ReadBuffer error:", err)
|
gLog.Println(LvDEBUG, "s2c ul.ReadBuffer error:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req := P2PHandshakeReq{}
|
req := P2PHandshakeReq{}
|
||||||
@@ -490,7 +489,7 @@ func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) {
|
|||||||
defer gLog.Printf(LvDEBUG, "connectUnderlayTCP6 %s end ", t.config.LogPeerNode())
|
defer gLog.Printf(LvDEBUG, "connectUnderlayTCP6 %s end ", t.config.LogPeerNode())
|
||||||
var ul *underlayTCP6
|
var ul *underlayTCP6
|
||||||
if t.config.isUnderlayServer == 1 {
|
if t.config.isUnderlayServer == 1 {
|
||||||
t.pn.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
GNetwork.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
||||||
ul, err = listenTCP6(t.coneNatPort, UnderlayConnectTimeout)
|
ul, err = listenTCP6(t.coneNatPort, UnderlayConnectTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("listen TCP6 error:%s", err)
|
return nil, fmt.Errorf("listen TCP6 error:%s", err)
|
||||||
@@ -509,17 +508,17 @@ func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//else
|
//else
|
||||||
t.pn.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
GNetwork.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
||||||
gLog.Println(LvDEBUG, "TCP6 dial to ", t.config.peerIPv6)
|
gLog.Println(LvDEBUG, "TCP6 dial to ", t.config.peerIPv6)
|
||||||
ul, err = dialTCP6(t.config.peerIPv6, t.config.peerConeNatPort)
|
ul, err = dialTCP6(t.config.peerIPv6, t.config.peerConeNatPort)
|
||||||
if err != nil {
|
if err != nil || ul == nil {
|
||||||
return nil, fmt.Errorf("TCP6 dial to %s:%d error:%s", t.config.peerIPv6, t.config.peerConeNatPort, err)
|
return nil, fmt.Errorf("TCP6 dial to %s:%d error:%s", t.config.peerIPv6, t.config.peerConeNatPort, err)
|
||||||
}
|
}
|
||||||
handshakeBegin := time.Now()
|
handshakeBegin := time.Now()
|
||||||
ul.WriteBytes(MsgP2P, MsgTunnelHandshake, []byte("OpenP2P,hello"))
|
ul.WriteBytes(MsgP2P, MsgTunnelHandshake, []byte("OpenP2P,hello"))
|
||||||
_, buff, err := ul.ReadBuffer()
|
_, buff, errR := ul.ReadBuffer()
|
||||||
if err != nil {
|
if errR != nil {
|
||||||
return nil, fmt.Errorf("read MsgTunnelHandshake error:%s", err)
|
return nil, fmt.Errorf("read MsgTunnelHandshake error:%s", errR)
|
||||||
}
|
}
|
||||||
if buff != nil {
|
if buff != nil {
|
||||||
gLog.Println(LvDEBUG, string(buff))
|
gLog.Println(LvDEBUG, string(buff))
|
||||||
@@ -596,7 +595,7 @@ func (t *P2PTunnel) readLoop() {
|
|||||||
}
|
}
|
||||||
tunnelID := binary.LittleEndian.Uint64(body[:8])
|
tunnelID := binary.LittleEndian.Uint64(body[:8])
|
||||||
gLog.Printf(LvDev, "relay data to %d, len=%d", tunnelID, head.DataLen-RelayHeaderSize)
|
gLog.Printf(LvDev, "relay data to %d, len=%d", tunnelID, head.DataLen-RelayHeaderSize)
|
||||||
if err := t.pn.relay(tunnelID, body[RelayHeaderSize:]); err != nil {
|
if err := GNetwork.relay(tunnelID, body[RelayHeaderSize:]); err != nil {
|
||||||
gLog.Printf(LvERROR, "%s:%d relay to %d len=%d error:%s", t.config.LogPeerNode(), t.id, tunnelID, len(body), ErrRelayTunnelNotFound)
|
gLog.Printf(LvERROR, "%s:%d relay to %d len=%d error:%s", t.config.LogPeerNode(), t.id, tunnelID, len(body), ErrRelayTunnelNotFound)
|
||||||
}
|
}
|
||||||
case MsgRelayHeartbeat:
|
case MsgRelayHeartbeat:
|
||||||
@@ -608,7 +607,7 @@ func (t *P2PTunnel) readLoop() {
|
|||||||
// TODO: debug relay heartbeat
|
// TODO: debug relay heartbeat
|
||||||
gLog.Printf(LvDEBUG, "read MsgRelayHeartbeat from rtid:%d,appid:%d", req.RelayTunnelID, req.AppID)
|
gLog.Printf(LvDEBUG, "read MsgRelayHeartbeat from rtid:%d,appid:%d", req.RelayTunnelID, req.AppID)
|
||||||
// update app hbtime
|
// update app hbtime
|
||||||
t.pn.updateAppHeartbeat(req.AppID)
|
GNetwork.updateAppHeartbeat(req.AppID)
|
||||||
req.From = gConf.Network.Node
|
req.From = gConf.Network.Node
|
||||||
t.WriteMessage(req.RelayTunnelID, MsgP2P, MsgRelayHeartbeatAck, &req)
|
t.WriteMessage(req.RelayTunnelID, MsgP2P, MsgRelayHeartbeatAck, &req)
|
||||||
case MsgRelayHeartbeatAck:
|
case MsgRelayHeartbeatAck:
|
||||||
@@ -620,7 +619,7 @@ func (t *P2PTunnel) readLoop() {
|
|||||||
}
|
}
|
||||||
// TODO: debug relay heartbeat
|
// TODO: debug relay heartbeat
|
||||||
gLog.Printf(LvDEBUG, "read MsgRelayHeartbeatAck to appid:%d", req.AppID)
|
gLog.Printf(LvDEBUG, "read MsgRelayHeartbeatAck to appid:%d", req.AppID)
|
||||||
t.pn.updateAppHeartbeat(req.AppID)
|
GNetwork.updateAppHeartbeat(req.AppID)
|
||||||
case MsgOverlayConnectReq:
|
case MsgOverlayConnectReq:
|
||||||
req := OverlayConnectReq{}
|
req := OverlayConnectReq{}
|
||||||
if err := json.Unmarshal(body, &req); err != nil {
|
if err := json.Unmarshal(body, &req); err != nil {
|
||||||
@@ -733,7 +732,7 @@ func (t *P2PTunnel) listen() error {
|
|||||||
FromIP: gConf.Network.publicIP,
|
FromIP: gConf.Network.publicIP,
|
||||||
ConeNatPort: t.coneNatPort,
|
ConeNatPort: t.coneNatPort,
|
||||||
ID: t.id,
|
ID: t.id,
|
||||||
PunchTs: uint64(time.Now().UnixNano() + int64(PunchTsDelay) - t.pn.dt),
|
PunchTs: uint64(time.Now().UnixNano() + int64(PunchTsDelay) - GNetwork.dt),
|
||||||
Version: OpenP2PVersion,
|
Version: OpenP2PVersion,
|
||||||
}
|
}
|
||||||
t.punchTs = rsp.PunchTs
|
t.punchTs = rsp.PunchTs
|
||||||
@@ -742,7 +741,7 @@ func (t *P2PTunnel) listen() error {
|
|||||||
rsp.IPv6 = gConf.IPv6()
|
rsp.IPv6 = gConf.IPv6()
|
||||||
}
|
}
|
||||||
|
|
||||||
t.pn.push(t.config.PeerNode, MsgPushConnectRsp, rsp)
|
GNetwork.push(t.config.PeerNode, MsgPushConnectRsp, rsp)
|
||||||
gLog.Printf(LvDEBUG, "p2ptunnel wait for connecting")
|
gLog.Printf(LvDEBUG, "p2ptunnel wait for connecting")
|
||||||
t.tunnelServer = true
|
t.tunnelServer = true
|
||||||
return t.start()
|
return t.start()
|
||||||
@@ -760,9 +759,9 @@ func (t *P2PTunnel) closeOverlayConns(appID uint64) {
|
|||||||
|
|
||||||
func (t *P2PTunnel) handleNodeData(head *openP2PHeader, body []byte, isRelay bool) {
|
func (t *P2PTunnel) handleNodeData(head *openP2PHeader, body []byte, isRelay bool) {
|
||||||
gLog.Printf(LvDev, "%d tunnel read node data bodylen=%d, relay=%t", t.id, head.DataLen, isRelay)
|
gLog.Printf(LvDev, "%d tunnel read node data bodylen=%d, relay=%t", t.id, head.DataLen, isRelay)
|
||||||
ch := t.pn.nodeData
|
ch := GNetwork.nodeData
|
||||||
// if body[9] == 1 { // TODO: deal relay
|
// if body[9] == 1 { // TODO: deal relay
|
||||||
// ch = t.pn.nodeDataSmall
|
// ch = GNetwork.nodeDataSmall
|
||||||
// gLog.Printf(LvDEBUG, "read icmp %d", time.Now().Unix())
|
// gLog.Printf(LvDEBUG, "read icmp %d", time.Now().Unix())
|
||||||
// }
|
// }
|
||||||
if isRelay {
|
if isRelay {
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package openp2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/icmp"
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义ICMP回显请求和应答的结构
|
||||||
|
type ICMPMessage struct {
|
||||||
|
Type uint8
|
||||||
|
Code uint8
|
||||||
|
Checksum uint16
|
||||||
|
Ident uint16
|
||||||
|
Seq uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ping sends an ICMP Echo request to the specified host and returns the response time.
|
||||||
|
func Ping(host string) (time.Duration, error) {
|
||||||
|
// Resolve the IP address of the host
|
||||||
|
ipAddr, err := net.ResolveIPAddr("ip4", host)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to resolve host: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an ICMP listener
|
||||||
|
conn, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to create ICMP connection: %v", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
// Create an ICMP Echo request message
|
||||||
|
message := icmp.Message{
|
||||||
|
Type: ipv4.ICMPTypeEcho,
|
||||||
|
Code: 0,
|
||||||
|
Body: &icmp.Echo{
|
||||||
|
ID: os.Getpid() & 0xffff,
|
||||||
|
Seq: 1,
|
||||||
|
Data: []byte("HELLO-R-U-THERE"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal the message into binary form
|
||||||
|
messageBytes, err := message.Marshal(nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to marshal ICMP message: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the ICMP Echo request
|
||||||
|
start := time.Now()
|
||||||
|
if _, err := conn.WriteTo(messageBytes, ipAddr); err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to send ICMP request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a deadline for the response
|
||||||
|
err = conn.SetReadDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to set read deadline: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the ICMP response
|
||||||
|
response := make([]byte, 1500)
|
||||||
|
n, _, err := conn.ReadFrom(response)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to read ICMP response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the ICMP response message
|
||||||
|
parsedMessage, err := icmp.ParseMessage(ipv4.ICMPTypeEchoReply.Protocol(), response[:n])
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to parse ICMP response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the response is an Echo reply
|
||||||
|
if parsedMessage.Type == ipv4.ICMPTypeEchoReply {
|
||||||
|
duration := time.Since(start)
|
||||||
|
return duration, nil
|
||||||
|
} else {
|
||||||
|
return 0, fmt.Errorf("unexpected ICMP message: %+v", parsedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-2
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const OpenP2PVersion = "3.19.0"
|
const OpenP2PVersion = "3.21.10"
|
||||||
const ProductName string = "openp2p"
|
const ProductName string = "openp2p"
|
||||||
const LeastSupportVersion = "3.0.0"
|
const LeastSupportVersion = "3.0.0"
|
||||||
const SyncServerTimeVersion = "3.9.0"
|
const SyncServerTimeVersion = "3.9.0"
|
||||||
@@ -217,6 +217,12 @@ const (
|
|||||||
MsgSDWANInfoRsp
|
MsgSDWANInfoRsp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MsgNATDetect
|
||||||
|
const (
|
||||||
|
MsgNAT = iota
|
||||||
|
MsgPublicIP
|
||||||
|
)
|
||||||
|
|
||||||
func newMessage(mainType uint16, subType uint16, packet interface{}) ([]byte, error) {
|
func newMessage(mainType uint16, subType uint16, packet interface{}) ([]byte, error) {
|
||||||
data, err := json.Marshal(packet)
|
data, err := json.Marshal(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -495,7 +501,7 @@ type SDWANInfo struct {
|
|||||||
ForceRelay int32 `json:"forceRelay,omitempty"`
|
ForceRelay int32 `json:"forceRelay,omitempty"`
|
||||||
PunchPriority int32 `json:"punchPriority,omitempty"`
|
PunchPriority int32 `json:"punchPriority,omitempty"`
|
||||||
Enable int32 `json:"enable,omitempty"`
|
Enable int32 `json:"enable,omitempty"`
|
||||||
Nodes []SDWANNode
|
Nodes []*SDWANNode
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
+40
-9
@@ -52,18 +52,36 @@ type p2pSDWAN struct {
|
|||||||
internalRoute *IPTree
|
internalRoute *IPTree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *p2pSDWAN) reset() {
|
||||||
|
gLog.Println(LvINFO, "reset sdwan when network disconnected")
|
||||||
|
// clear sysroute
|
||||||
|
delRoutesByGateway(s.gateway.String())
|
||||||
|
// clear internel route
|
||||||
|
s.internalRoute = NewIPTree("")
|
||||||
|
// clear p2papp
|
||||||
|
for _, node := range gConf.getAddNodes() {
|
||||||
|
gConf.delete(AppConfig{SrcPort: 0, PeerNode: node.Name})
|
||||||
|
}
|
||||||
|
|
||||||
|
gConf.resetSDWAN()
|
||||||
|
}
|
||||||
func (s *p2pSDWAN) init(name string) error {
|
func (s *p2pSDWAN) init(name string) error {
|
||||||
if gConf.getSDWAN().Gateway == "" {
|
if gConf.getSDWAN().Gateway == "" {
|
||||||
gLog.Println(LvDEBUG, "not in sdwan clear all ")
|
gLog.Println(LvDEBUG, "sdwan init: not in sdwan clear all ")
|
||||||
}
|
}
|
||||||
if s.internalRoute == nil {
|
if s.internalRoute == nil {
|
||||||
s.internalRoute = NewIPTree("")
|
s.internalRoute = NewIPTree("")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.nodeName = name
|
s.nodeName = name
|
||||||
s.gateway, s.subnet, _ = net.ParseCIDR(gConf.getSDWAN().Gateway)
|
if gw, sn, err := net.ParseCIDR(gConf.getSDWAN().Gateway); err == nil { // preserve old gateway
|
||||||
|
s.gateway = gw
|
||||||
|
s.subnet = sn
|
||||||
|
}
|
||||||
|
|
||||||
for _, node := range gConf.getDelNodes() {
|
for _, node := range gConf.getDelNodes() {
|
||||||
gLog.Println(LvDEBUG, "deal deleted node: ", node.Name)
|
gLog.Println(LvDEBUG, "sdwan init: deal deleted node: ", node.Name)
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: delRoute: %s, %s ", node.IP, s.gateway.String())
|
||||||
delRoute(node.IP, s.gateway.String())
|
delRoute(node.IP, s.gateway.String())
|
||||||
s.internalRoute.Del(node.IP, node.IP)
|
s.internalRoute.Del(node.IP, node.IP)
|
||||||
ipNum, _ := inetAtoN(node.IP)
|
ipNum, _ := inetAtoN(node.IP)
|
||||||
@@ -88,24 +106,26 @@ func (s *p2pSDWAN) init(name string) error {
|
|||||||
}
|
}
|
||||||
s.internalRoute.Del(minIP.String(), maxIP.String())
|
s.internalRoute.Del(minIP.String(), maxIP.String())
|
||||||
delRoute(ipnet.String(), s.gateway.String())
|
delRoute(ipnet.String(), s.gateway.String())
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: resource delRoute: %s, %s ", ipnet.String(), s.gateway.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, node := range gConf.getAddNodes() {
|
for _, node := range gConf.getAddNodes() {
|
||||||
gLog.Println(LvDEBUG, "deal add node: ", node.Name)
|
gLog.Println(LvDEBUG, "sdwan init: deal add node: ", node.Name)
|
||||||
ipNet := &net.IPNet{
|
ipNet := &net.IPNet{
|
||||||
IP: net.ParseIP(node.IP),
|
IP: net.ParseIP(node.IP),
|
||||||
Mask: s.subnet.Mask,
|
Mask: s.subnet.Mask,
|
||||||
}
|
}
|
||||||
if node.Name == s.nodeName {
|
if node.Name == s.nodeName {
|
||||||
s.virtualIP = ipNet
|
s.virtualIP = ipNet
|
||||||
gLog.Println(LvINFO, "start tun ", ipNet.String())
|
gLog.Println(LvINFO, "sdwan init: start tun ", ipNet.String())
|
||||||
err := s.StartTun()
|
err := s.StartTun()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Println(LvERROR, "start tun error:", err)
|
gLog.Println(LvERROR, "sdwan init: start tun error:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
gLog.Println(LvINFO, "start tun ok")
|
gLog.Println(LvINFO, "sdwan init: start tun ok")
|
||||||
allowTunForward()
|
allowTunForward()
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: addRoute %s %s %s", s.subnet.String(), s.gateway.String(), s.tun.tunName)
|
||||||
addRoute(s.subnet.String(), s.gateway.String(), s.tun.tunName)
|
addRoute(s.subnet.String(), s.gateway.String(), s.tun.tunName)
|
||||||
// addRoute("255.255.255.255/32", s.gateway.String(), s.tun.tunName) // for broadcast
|
// addRoute("255.255.255.255/32", s.gateway.String(), s.tun.tunName) // for broadcast
|
||||||
// addRoute("224.0.0.0/4", s.gateway.String(), s.tun.tunName) // for multicast
|
// addRoute("224.0.0.0/4", s.gateway.String(), s.tun.tunName) // for multicast
|
||||||
@@ -124,18 +144,28 @@ func (s *p2pSDWAN) init(name string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(node.Resource) > 0 {
|
if len(node.Resource) > 0 {
|
||||||
gLog.Printf(LvINFO, "deal add node: %s resource: %s", node.Name, node.Resource)
|
gLog.Printf(LvINFO, "sdwan init: deal add node: %s resource: %s", node.Name, node.Resource)
|
||||||
arr := strings.Split(node.Resource, ",")
|
arr := strings.Split(node.Resource, ",")
|
||||||
for _, r := range arr {
|
for _, r := range arr {
|
||||||
// add internal route
|
// add internal route
|
||||||
_, ipnet, err := net.ParseCIDR(r)
|
_, ipnet, err := net.ParseCIDR(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error parsing CIDR:", err)
|
fmt.Println("sdwan init: Error parsing CIDR:", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ipnet.Contains(net.ParseIP(gConf.Network.localIP)) { // local ip and resource in the same lan
|
if ipnet.Contains(net.ParseIP(gConf.Network.localIP)) { // local ip and resource in the same lan
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: local ip %s in this resource %s, ignore", gConf.Network.localIP, ipnet.IP.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// local net could access this single ip
|
||||||
|
if ipnet.Mask[0] == 255 && ipnet.Mask[1] == 255 && ipnet.Mask[2] == 255 && ipnet.Mask[3] == 255 {
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: ping %s start", ipnet.IP.String())
|
||||||
|
if _, err := Ping(ipnet.IP.String()); err == nil {
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: ping %s ok, ignore this resource", ipnet.IP.String())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: ping %s failed", ipnet.IP.String())
|
||||||
|
}
|
||||||
minIP := ipnet.IP
|
minIP := ipnet.IP
|
||||||
maxIP := make(net.IP, len(minIP))
|
maxIP := make(net.IP, len(minIP))
|
||||||
copy(maxIP, minIP)
|
copy(maxIP, minIP)
|
||||||
@@ -144,6 +174,7 @@ func (s *p2pSDWAN) init(name string) error {
|
|||||||
}
|
}
|
||||||
s.internalRoute.Add(minIP.String(), maxIP.String(), &sdwanNode{name: node.Name, id: NodeNameToID(node.Name)})
|
s.internalRoute.Add(minIP.String(), maxIP.String(), &sdwanNode{name: node.Name, id: NodeNameToID(node.Name)})
|
||||||
// add sys route
|
// add sys route
|
||||||
|
gLog.Printf(LvDEBUG, "sdwan init: addRoute %s %s %s", ipnet.String(), s.gateway.String(), s.tun.tunName)
|
||||||
addRoute(ipnet.String(), s.gateway.String(), s.tun.tunName)
|
addRoute(ipnet.String(), s.gateway.String(), s.tun.tunName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ func DefaultReadBuffer(ul underlay) (*openP2PHeader, []byte, error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
head, err := decodeHeader(headBuf)
|
head, err := decodeHeader(headBuf)
|
||||||
if err != nil {
|
if err != nil || head.MainType > 16 {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
dataBuf := make([]byte, head.DataLen)
|
dataBuf := make([]byte, head.DataLen)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func listenTCP(host string, port int, localPort int, mode string, t *P2PTunnel)
|
|||||||
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
if compareVersion(t.config.peerVersion, SyncServerTimeVersion) < 0 {
|
||||||
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
gLog.Printf(LvDEBUG, "peer version %s less than %s", t.config.peerVersion, SyncServerTimeVersion)
|
||||||
} else {
|
} else {
|
||||||
ts := time.Duration(int64(t.punchTs) + t.pn.dt - time.Now().UnixNano())
|
ts := time.Duration(int64(t.punchTs) + GNetwork.dt - time.Now().UnixNano())
|
||||||
gLog.Printf(LvDEBUG, "sleep %d ms", ts/time.Millisecond)
|
gLog.Printf(LvDEBUG, "sleep %d ms", ts/time.Millisecond)
|
||||||
time.Sleep(ts)
|
time.Sleep(ts)
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func listenTCP(host string, port int, localPort int, mode string, t *P2PTunnel)
|
|||||||
utcp.WriteBytes(MsgP2P, MsgTunnelHandshakeAck, buff)
|
utcp.WriteBytes(MsgP2P, MsgTunnelHandshakeAck, buff)
|
||||||
return utcp, nil
|
return utcp, nil
|
||||||
}
|
}
|
||||||
t.pn.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
GNetwork.push(t.config.PeerNode, MsgPushUnderlayConnect, nil)
|
||||||
tid := t.id
|
tid := t.id
|
||||||
if compareVersion(t.config.peerVersion, PublicIPVersion) < 0 { // old version
|
if compareVersion(t.config.peerVersion, PublicIPVersion) < 0 { // old version
|
||||||
ipBytes := net.ParseIP(t.config.peerIP).To4()
|
ipBytes := net.ParseIP(t.config.peerIP).To4()
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ func (vl *v4Listener) handleConnection(c net.Conn) {
|
|||||||
utcp.SetReadDeadline(time.Now().Add(UnderlayTCPConnectTimeout))
|
utcp.SetReadDeadline(time.Now().Add(UnderlayTCPConnectTimeout))
|
||||||
_, buff, err := utcp.ReadBuffer()
|
_, buff, err := utcp.ReadBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Printf(LvERROR, "utcp.ReadBuffer error:", err)
|
gLog.Println(LvERROR, "utcp.ReadBuffer error:", err)
|
||||||
}
|
}
|
||||||
utcp.WriteBytes(MsgP2P, MsgTunnelHandshakeAck, buff)
|
utcp.WriteBytes(MsgP2P, MsgTunnelHandshakeAck, buff)
|
||||||
var tid uint64
|
var tid uint64
|
||||||
|
|||||||
Reference in New Issue
Block a user