Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
||||||
|
|||||||
@@ -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].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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+2
-1
@@ -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 {
|
||||||
@@ -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))
|
||||||
|
|||||||
+6
-6
@@ -426,7 +426,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 +455,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{}
|
||||||
@@ -512,14 +512,14 @@ func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) {
|
|||||||
t.pn.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, ReadMsgTimeout)
|
t.pn.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))
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const OpenP2PVersion = "3.19.0"
|
const OpenP2PVersion = "3.21.8"
|
||||||
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"
|
||||||
@@ -495,7 +495,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
@@ -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