Compare commits

...
5 Commits
Author SHA1 Message Date
TenderIronh 2275620060 dartnode 2025-06-10 15:12:53 +08:00
TenderIronh 29faf4a950 nil pointer 2025-02-04 23:10:47 +08:00
TenderIronh 080e6af779 fix public ip detect bug 2024-12-02 21:10:15 +08:00
TenderIronh 77bfa45172 portmap loss & android ipv6 failed & public ip detect 2024-11-21 10:31:07 +08:00
TenderIronh 3616768682 rename 2024-11-21 10:29:06 +08:00
14 changed files with 105 additions and 89 deletions
+2
View File
@@ -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
[![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
@@ -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 -1
View File
@@ -239,7 +239,7 @@ func (c *Config) delete(app AppConfig) {
defer c.save() defer c.save()
for i := 0; i < len(c.Apps); i++ { for i := 0; i < len(c.Apps); i++ {
if (app.SrcPort != 0 && c.Apps[i].Protocol == app.Protocol && c.Apps[i].SrcPort == app.SrcPort) || // normal app if (app.SrcPort != 0 && c.Apps[i].Protocol == app.Protocol && c.Apps[i].SrcPort == app.SrcPort) || // normal app
(app.SrcPort == 0 && c.Apps[i].PeerNode == app.PeerNode) { // memapp (app.SrcPort == 0 && c.Apps[i].SrcPort == 0 && c.Apps[i].PeerNode == app.PeerNode) { // memapp
if i == len(c.Apps)-1 { if i == len(c.Apps)-1 {
c.Apps = c.Apps[:i] c.Apps = c.Apps[:i]
} else { } else {
+7 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -115,7 +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.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
@@ -468,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),
+31 -32
View File
@@ -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
} }
@@ -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,7 +508,7 @@ 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 || ul == nil { if err != nil || ul == nil {
@@ -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 {
+8 -2
View File
@@ -10,7 +10,7 @@ import (
"time" "time"
) )
const OpenP2PVersion = "3.21.8" 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 {
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 23 KiB

+11 -12
View File
@@ -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
) )