Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2275620060 | ||
|
|
29faf4a950 | ||
|
|
080e6af779 | ||
|
|
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
|
||||||
@@ -162,3 +162,5 @@ Email: [email protected] [email protected]
|
|||||||
## Disclaimer
|
## Disclaimer
|
||||||
This project is open source for everyone to learn and use for free. It is forbidden to be used for illegal purposes. Any loss caused by improper use of this project or accident, this project and related personnel will not bear any responsibility.
|
This project is open source for everyone to learn and use for free. It is forbidden to be used for illegal purposes. Any loss caused by improper use of this project or accident, this project and related personnel will not bear any responsibility.
|
||||||
|
|
||||||
|
## Thanks
|
||||||
|
[](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
|
||||||
+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
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -60,6 +60,7 @@ func (d *daemon) run() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, "-nv")
|
args = append(args, "-nv")
|
||||||
for {
|
for {
|
||||||
// start worker
|
// start worker
|
||||||
@@ -72,6 +73,7 @@ func (d *daemon) run() {
|
|||||||
}
|
}
|
||||||
gLog.Println(LvINFO, "start worker process, args:", args)
|
gLog.Println(LvINFO, "start worker process, args:", args)
|
||||||
execSpec := &os.ProcAttr{Env: append(os.Environ(), "GOTRACEBACK=crash"), Files: []*os.File{os.Stdin, os.Stdout, f}}
|
execSpec := &os.ProcAttr{Env: append(os.Environ(), "GOTRACEBACK=crash"), Files: []*os.File{os.Stdin, os.Stdout, f}}
|
||||||
|
lastRebootTime := time.Now()
|
||||||
p, err := os.StartProcess(binPath, args, execSpec)
|
p, err := os.StartProcess(binPath, args, execSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gLog.Printf(LvERROR, "start worker error:%s", err)
|
gLog.Printf(LvERROR, "start worker error:%s", err)
|
||||||
@@ -88,8 +90,11 @@ func (d *daemon) run() {
|
|||||||
if !d.running {
|
if !d.running {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gLog.Printf(LvERROR, "worker stop, restart it after 10s")
|
if time.Since(lastRebootTime) < time.Second*10 {
|
||||||
time.Sleep(time.Second * 10)
|
gLog.Printf(LvERROR, "worker stop, restart it after 10s")
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+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)
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-18
@@ -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
|
||||||
@@ -121,18 +121,6 @@ func publicIPTest(publicIP string, echoPort int) (hasPublicIP int, hasUPNPorNATP
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer echoConn.Close()
|
defer echoConn.Close()
|
||||||
go func() {
|
|
||||||
// close outside for breaking the ReadFromUDP
|
|
||||||
// wait 30s for echo testing
|
|
||||||
buf := make([]byte, 1600)
|
|
||||||
echoConn.SetReadDeadline(time.Now().Add(time.Second * 30))
|
|
||||||
n, addr, err := echoConn.ReadFromUDP(buf)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
echoConn.WriteToUDP(buf[0:n], addr)
|
|
||||||
gLog.Println(LvDEBUG, "echo server end")
|
|
||||||
}()
|
|
||||||
// testing for public ip
|
// testing for public ip
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
@@ -164,17 +152,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 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
buf := make([]byte, 1600)
|
buf := make([]byte, 1600)
|
||||||
|
|
||||||
// wait for echo testing
|
// wait for echo testing
|
||||||
conn.SetReadDeadline(time.Now().Add(PublicIPEchoTimeout))
|
echoConn.SetReadDeadline(time.Now().Add(PublicIPEchoTimeout))
|
||||||
_, _, err = conn.ReadFromUDP(buf)
|
nRead, _, err := echoConn.ReadFromUDP(buf)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
|
gLog.Println(LvDEBUG, "PublicIP detect error:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
natRsp := NatDetectRsp{}
|
||||||
|
err = json.Unmarshal(buf[openP2PHeaderSize:nRead], &natRsp)
|
||||||
|
if err != nil {
|
||||||
|
gLog.Println(LvDEBUG, "PublicIP detect error:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
pn.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-3
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const OpenP2PVersion = "3.19.0"
|
const OpenP2PVersion = "3.21.12"
|
||||||
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"
|
||||||
@@ -167,7 +167,7 @@ const (
|
|||||||
MaxRetry = 10
|
MaxRetry = 10
|
||||||
Cone2ConeTCPPunchMaxRetry = 1
|
Cone2ConeTCPPunchMaxRetry = 1
|
||||||
Cone2ConeUDPPunchMaxRetry = 1
|
Cone2ConeUDPPunchMaxRetry = 1
|
||||||
PublicIPEchoTimeout = time.Second * 1
|
PublicIPEchoTimeout = time.Second * 3
|
||||||
NatTestTimeout = time.Second * 5
|
NatTestTimeout = time.Second * 5
|
||||||
UDPReadTimeout = time.Second * 5
|
UDPReadTimeout = time.Second * 5
|
||||||
ClientAPITimeout = time.Second * 10
|
ClientAPITimeout = time.Second * 10
|
||||||
@@ -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
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 23 KiB |
@@ -8,17 +8,16 @@ require (
|
|||||||
github.com/openp2p-cn/go-reuseport v0.3.2
|
github.com/openp2p-cn/go-reuseport v0.3.2
|
||||||
github.com/openp2p-cn/service v1.0.0
|
github.com/openp2p-cn/service v1.0.0
|
||||||
github.com/openp2p-cn/totp v0.0.0-20230421034602-0f3320ffb25e
|
github.com/openp2p-cn/totp v0.0.0-20230421034602-0f3320ffb25e
|
||||||
github.com/openp2p-cn/wireguard-go v0.0.20240223
|
|
||||||
github.com/quic-go/quic-go v0.34.0
|
github.com/quic-go/quic-go v0.34.0
|
||||||
github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54
|
||||||
github.com/xtaci/kcp-go/v5 v5.5.17
|
github.com/xtaci/kcp-go/v5 v5.5.17
|
||||||
golang.org/x/sys v0.21.0
|
golang.org/x/sys v0.26.0
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3
|
golang.zx2c4.com/wireguard/windows v0.5.3
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.7.0-rc.1 // indirect
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||||
github.com/kardianos/service v1.2.2 // indirect
|
github.com/kardianos/service v1.2.2 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||||
@@ -30,13 +29,13 @@ require (
|
|||||||
github.com/templexxx/cpu v0.1.0 // indirect
|
github.com/templexxx/cpu v0.1.0 // indirect
|
||||||
github.com/templexxx/xorsimd v0.4.2 // indirect
|
github.com/templexxx/xorsimd v0.4.2 // indirect
|
||||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
|
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
golang.org/x/crypto v0.28.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect
|
||||||
golang.org/x/mod v0.18.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
golang.org/x/tools v0.22.0 // indirect
|
golang.org/x/tools v0.26.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
google.golang.org/protobuf v1.33.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
gvisor.dev/gvisor v0.0.0-20241128011400-745828301c93 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user