Compare commits

...
3 Commits
Author SHA1 Message Date
TenderIronh c3a43be3cc improve gatway and p2papp reconnect 2022-11-25 23:55:33 +08:00
TenderIronh c8b8bf05a5 support openwrt and improve app and gateway reconnect time 2022-11-18 23:19:47 +08:00
hhd 8311341960 readloop error 2022-11-10 23:34:04 +08:00
11 changed files with 72 additions and 67 deletions
-1
View File
@@ -20,7 +20,6 @@ import (
const MinNodeNameLen = 8 const MinNodeNameLen = 8
func getmac(ip string) string { func getmac(ip string) string {
//get mac relative to the ip address which connected to the mq.
ifaces, err := net.Interfaces() ifaces, err := net.Interfaces()
if err != nil { if err != nil {
return "" return ""
+7 -7
View File
@@ -6,7 +6,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/kardianos/service" "github.com/openp2p-cn/service"
) )
type daemon struct { type daemon struct {
@@ -44,9 +44,9 @@ func (d *daemon) run() {
} }
gLog.Println(LvINFO, mydir) gLog.Println(LvINFO, mydir)
conf := &service.Config{ conf := &service.Config{
Name: ProducnName, Name: ProductName,
DisplayName: ProducnName, DisplayName: ProductName,
Description: ProducnName, Description: ProductName,
Executable: binPath, Executable: binPath,
} }
@@ -95,9 +95,9 @@ func (d *daemon) run() {
func (d *daemon) Control(ctrlComm string, exeAbsPath string, args []string) error { func (d *daemon) Control(ctrlComm string, exeAbsPath string, args []string) error {
svcConfig := &service.Config{ svcConfig := &service.Config{
Name: ProducnName, Name: ProductName,
DisplayName: ProducnName, DisplayName: ProductName,
Description: ProducnName, Description: ProductName,
Executable: exeAbsPath, Executable: exeAbsPath,
Arguments: args, Arguments: args,
} }
-1
View File
@@ -101,7 +101,6 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error {
msg := TunnelMsg{ID: t.id} msg := TunnelMsg{ID: t.id}
pn.push(r.From, MsgPushAddRelayTunnelRsp, msg) pn.push(r.From, MsgPushAddRelayTunnelRsp, msg)
} }
}(req) }(req)
case MsgPushAPPKey: case MsgPushAPPKey:
req := APPKeySync{} req := APPKeySync{}
+2 -1
View File
@@ -17,7 +17,7 @@ import (
// ./openp2p install -node hhd1207-222 -token YOUR-TOKEN -sharebandwidth 0 -peernode hhdhome-n1 -dstip 127.0.0.1 -dstport 50022 -protocol tcp -srcport 22 // ./openp2p install -node hhd1207-222 -token YOUR-TOKEN -sharebandwidth 0 -peernode hhdhome-n1 -dstip 127.0.0.1 -dstport 50022 -protocol tcp -srcport 22
func install() { func install() {
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion) gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
gLog.Println(LvINFO, "Contact: QQ: 16947733, Email: [email protected]") gLog.Println(LvINFO, "Contact: QQ group 16947733, Email [email protected]")
gLog.Println(LvINFO, "install start") gLog.Println(LvINFO, "install start")
defer gLog.Println(LvINFO, "install end") defer gLog.Println(LvINFO, "install end")
// auto uninstall // auto uninstall
@@ -74,6 +74,7 @@ func install() {
} else { } else {
gLog.Println(LvINFO, "start openp2p service ok.") gLog.Println(LvINFO, "start openp2p service ok.")
} }
gLog.Println(LvINFO, "Visit WebUI on https://console.openp2p.cn")
} }
func installByFilename() { func installByFilename() {
+3 -3
View File
@@ -13,7 +13,7 @@ func Run() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
baseDir := filepath.Dir(os.Args[0]) baseDir := filepath.Dir(os.Args[0])
os.Chdir(baseDir) // for system service os.Chdir(baseDir) // for system service
gLog = NewLogger(baseDir, ProducnName, LvDEBUG, 1024*1024, LogFileAndConsole) gLog = NewLogger(baseDir, ProductName, LvDEBUG, 1024*1024, LogFileAndConsole)
// TODO: install sub command, deamon process // TODO: install sub command, deamon process
if len(os.Args) > 1 { if len(os.Args) > 1 {
switch os.Args[1] { switch os.Args[1] {
@@ -21,7 +21,7 @@ func Run() {
fmt.Println(OpenP2PVersion) fmt.Println(OpenP2PVersion)
return return
case "update": case "update":
gLog = NewLogger(baseDir, ProducnName, LvDEBUG, 1024*1024, LogFileAndConsole) gLog = NewLogger(baseDir, ProductName, LvDEBUG, 1024*1024, LogFileAndConsole)
targetPath := filepath.Join(defaultInstallPath, defaultBinName) targetPath := filepath.Join(defaultInstallPath, defaultBinName)
d := daemon{} d := daemon{}
err := d.Control("restart", targetPath, nil) err := d.Control("restart", targetPath, nil)
@@ -70,7 +70,7 @@ var network *P2PNetwork
func RunAsModule(baseDir string, token string, bw int, logLevel int) *P2PNetwork { func RunAsModule(baseDir string, token string, bw int, logLevel int) *P2PNetwork {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
os.Chdir(baseDir) // for system service os.Chdir(baseDir) // for system service
gLog = NewLogger(baseDir, ProducnName, LvDEBUG, 1024*1024, LogFileAndConsole) gLog = NewLogger(baseDir, ProductName, LvDEBUG, 1024*1024, LogFileAndConsole)
parseParams("") parseParams("")
+4 -1
View File
@@ -204,12 +204,15 @@ func (app *p2pApp) listen() error {
if app.rtid != 0 { if app.rtid != 0 {
go app.relayHeartbeatLoop() go app.relayHeartbeatLoop()
} }
for app.tunnel.isRuning() && app.running { for app.tunnel.isRuning() {
if app.config.Protocol == "udp" { if app.config.Protocol == "udp" {
app.listenUDP() app.listenUDP()
} else { } else {
app.listenTCP() app.listenTCP()
} }
if !app.running {
break
}
time.Sleep(time.Second * 10) time.Sleep(time.Second * 10)
} }
return nil return nil
+44 -44
View File
@@ -7,7 +7,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math"
"math/rand" "math/rand"
"net/http" "net/http"
"net/url" "net/url"
@@ -24,15 +23,15 @@ var (
) )
type P2PNetwork struct { type P2PNetwork struct {
conn *websocket.Conn conn *websocket.Conn
online bool online bool
running bool running bool
restartCh chan bool restartCh chan bool
wg sync.WaitGroup wgReconnect sync.WaitGroup
writeMtx sync.Mutex writeMtx sync.Mutex
serverTs int64 serverTs int64
localTs int64 localTs int64
hbTime time.Time hbTime time.Time
// msgMap sync.Map // msgMap sync.Map
msgMap map[uint64]chan []byte //key: nodeID msgMap map[uint64]chan []byte //key: nodeID
msgMapMtx sync.Mutex msgMapMtx sync.Mutex
@@ -64,18 +63,16 @@ func P2PNetworkInstance(config *NetworkConfig) *P2PNetwork {
} }
func (pn *P2PNetwork) run() { func (pn *P2PNetwork) run() {
go pn.readLoop()
go pn.autorunApp() go pn.autorunApp()
heartbeatTimer := time.NewTicker(NetworkHeartbeatTime) heartbeatTimer := time.NewTicker(NetworkHeartbeatTime)
for pn.running { for pn.running {
select { select {
case <-heartbeatTimer.C: // TODO: deal with connect failed, no send hb case <-heartbeatTimer.C:
pn.write(MsgHeartbeat, 0, "") pn.write(MsgHeartbeat, 0, "")
case <-pn.restartCh: case <-pn.restartCh:
pn.online = false pn.online = false
pn.wg.Wait() // wait read/write goroutine exited pn.wgReconnect.Wait() // wait read/write goroutine end
time.Sleep(NetworkHeartbeatTime)
err := pn.init() err := pn.init()
if err != nil { if err != nil {
gLog.Println(LvERROR, "P2PNetwork init error:", err) gLog.Println(LvERROR, "P2PNetwork init error:", err)
@@ -130,14 +127,12 @@ func (pn *P2PNetwork) runAll() {
} }
config.retryNum++ config.retryNum++
config.retryTime = time.Now() config.retryTime = time.Now()
increase := math.Pow(1.5, float64(config.retryNum)) // exponential increase retry time. 1.5^x if config.retryNum > 20 {
if increase > 900 {
increase = 900
config.Enabled = 0 config.Enabled = 0
gLog.Printf(LvWARN, "app %s has stopped retry, manually enable it on Web console", config.AppName) gLog.Printf(LvWARN, "app %s has stopped retry, manually enable it on Web console", config.AppName)
continue continue
} }
config.nextRetryTime = time.Now().Add(time.Second * time.Duration(increase)) config.nextRetryTime = time.Now().Add(time.Second * 10)
config.connectTime = time.Now() config.connectTime = time.Now()
config.peerToken = pn.config.Token config.peerToken = pn.config.Token
gConf.mtx.Unlock() // AddApp will take a period of time gConf.mtx.Unlock() // AddApp will take a period of time
@@ -156,7 +151,6 @@ func (pn *P2PNetwork) autorunApp() {
continue continue
} }
pn.runAll() pn.runAll()
time.Sleep(time.Second * 10)
} }
gLog.Println(LvINFO, "autorunApp end") gLog.Println(LvINFO, "autorunApp end")
} }
@@ -372,7 +366,7 @@ func (pn *P2PNetwork) addDirectTunnel(config AppConfig, tid uint64) (*P2PTunnel,
gLog.Println(LvERROR, "init error:", initErr) gLog.Println(LvERROR, "init error:", initErr)
return nil, initErr return nil, initErr
} }
err := ErrorHandshake var err error
// try TCP6 // try TCP6
if IsIPv6(t.config.peerIPv6) && IsIPv6(t.pn.config.publicIPv6) { if IsIPv6(t.config.peerIPv6) && IsIPv6(t.pn.config.publicIPv6) {
gLog.Println(LvINFO, "try TCP6") gLog.Println(LvINFO, "try TCP6")
@@ -418,7 +412,7 @@ func (pn *P2PNetwork) addDirectTunnel(config AppConfig, tid uint64) (*P2PTunnel,
return t, nil return t, nil
} }
} }
return nil, err return nil, ErrorHandshake // only ErrorHandshake will try relay
} }
func (pn *P2PNetwork) newTunnel(t *P2PTunnel, tid uint64, isClient bool) error { func (pn *P2PNetwork) newTunnel(t *P2PTunnel, tid uint64, isClient bool) error {
@@ -441,6 +435,11 @@ func (pn *P2PNetwork) newTunnel(t *P2PTunnel, tid uint64, isClient bool) error {
} }
func (pn *P2PNetwork) init() error { func (pn *P2PNetwork) init() error {
gLog.Println(LvINFO, "init start") gLog.Println(LvINFO, "init start")
go func() { //reconnect at least 5s
pn.wgReconnect.Add(1)
defer pn.wgReconnect.Done()
time.Sleep(NatTestTimeout)
}()
var err error var err error
for { for {
// detect nat type // detect nat type
@@ -488,30 +487,31 @@ func (pn *P2PNetwork) init() error {
err = errors.New("get local ip failed") err = errors.New("get local ip failed")
break break
} }
go pn.readLoop()
pn.config.mac = getmac(pn.config.localIP) pn.config.mac = getmac(pn.config.localIP)
pn.config.os = getOsName() pn.config.os = getOsName()
go func() {
req := ReportBasic{ req := ReportBasic{
Mac: pn.config.mac, Mac: pn.config.mac,
LanIP: pn.config.localIP, LanIP: pn.config.localIP,
OS: pn.config.os, OS: pn.config.os,
HasIPv4: pn.config.hasIPv4, HasIPv4: pn.config.hasIPv4,
HasUPNPorNATPMP: pn.config.hasUPNPorNATPMP, HasUPNPorNATPMP: pn.config.hasUPNPorNATPMP,
Version: OpenP2PVersion, Version: OpenP2PVersion,
}
rsp := netInfo()
gLog.Println(LvDEBUG, "netinfo:", rsp)
if rsp != nil && rsp.Country != "" {
if IsIPv6(rsp.IP.String()) {
pn.config.publicIPv6 = rsp.IP.String()
} }
req.NetInfo = *rsp rsp := netInfo()
} else { gLog.Println(LvDEBUG, "netinfo:", rsp)
pn.refreshIPv6(true) if rsp != nil && rsp.Country != "" {
} if IsIPv6(rsp.IP.String()) {
req.IPv6 = pn.config.publicIPv6 pn.config.publicIPv6 = rsp.IP.String()
pn.write(MsgReport, MsgReportBasic, &req) }
req.NetInfo = *rsp
} else {
pn.refreshIPv6(true)
}
req.IPv6 = pn.config.publicIPv6
pn.write(MsgReport, MsgReportBasic, &req)
}()
gLog.Println(LvDEBUG, "P2PNetwork init ok") gLog.Println(LvDEBUG, "P2PNetwork init ok")
break break
} }
@@ -572,8 +572,8 @@ func (pn *P2PNetwork) handleMessage(t int, msg []byte) {
func (pn *P2PNetwork) readLoop() { func (pn *P2PNetwork) readLoop() {
gLog.Printf(LvDEBUG, "P2PNetwork readLoop start") gLog.Printf(LvDEBUG, "P2PNetwork readLoop start")
pn.wg.Add(1) pn.wgReconnect.Add(1)
defer pn.wg.Done() defer pn.wgReconnect.Done()
for pn.running { for pn.running {
pn.conn.SetReadDeadline(time.Now().Add(NetworkHeartbeatTime + 10*time.Second)) pn.conn.SetReadDeadline(time.Now().Add(NetworkHeartbeatTime + 10*time.Second))
t, msg, err := pn.conn.ReadMessage() t, msg, err := pn.conn.ReadMessage()
+4 -1
View File
@@ -106,7 +106,7 @@ func (t *P2PTunnel) connect() error {
AppKey: appKey, AppKey: appKey,
Version: OpenP2PVersion, Version: OpenP2PVersion,
LinkMode: t.config.linkMode, LinkMode: t.config.linkMode,
IsUnderlayServer: t.config.isUnderlayServer ^ 1, IsUnderlayServer: t.config.isUnderlayServer ^ 1, // peer
} }
if req.Token == 0 { // no relay token if req.Token == 0 { // no relay token
req.Token = t.pn.config.Token req.Token = t.pn.config.Token
@@ -154,6 +154,9 @@ func (t *P2PTunnel) setRun(running bool) {
} }
func (t *P2PTunnel) isActive() bool { func (t *P2PTunnel) isActive() bool {
if !t.isRuning() {
return false
}
t.hbMtx.Lock() t.hbMtx.Lock()
defer t.hbMtx.Unlock() defer t.hbMtx.Unlock()
return time.Now().Before(t.hbTime.Add(TunnelIdleTimeout)) return time.Now().Before(t.hbTime.Add(TunnelIdleTimeout))
+3 -3
View File
@@ -10,8 +10,8 @@ import (
"time" "time"
) )
const OpenP2PVersion = "3.5.0" const OpenP2PVersion = "3.5.6"
const ProducnName string = "openp2p" const ProductName string = "openp2p"
const LeastSupportVersion = "3.0.0" const LeastSupportVersion = "3.0.0"
const ( const (
@@ -146,7 +146,7 @@ const (
MaxRetry = 10 MaxRetry = 10
RetryInterval = time.Second * 30 RetryInterval = time.Second * 30
PublicIPEchoTimeout = time.Second * 1 PublicIPEchoTimeout = time.Second * 1
NatTestTimeout = time.Second * 10 NatTestTimeout = time.Second * 5
ClientAPITimeout = time.Second * 10 ClientAPITimeout = time.Second * 10
MaxDirectTry = 3 MaxDirectTry = 3
) )
+3 -3
View File
@@ -45,9 +45,9 @@ func setFirewall() {
} }
if isXP { if isXP {
exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh firewall del allowedprogram "%s"`, fullPath)).Run() exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh firewall del allowedprogram "%s"`, fullPath)).Run()
exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh firewall add allowedprogram "%s" "%s" ENABLE`, ProducnName, fullPath)).Run() exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh firewall add allowedprogram "%s" "%s" ENABLE`, ProductName, fullPath)).Run()
} else { // win7 or later } else { // win7 or later
exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh advfirewall firewall del rule name="%s"`, ProducnName)).Run() exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh advfirewall firewall del rule name="%s"`, ProductName)).Run()
exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh advfirewall firewall add rule name="%s" dir=in action=allow program="%s" enable=yes`, ProducnName, fullPath)).Run() exec.Command("cmd.exe", `/c`, fmt.Sprintf(`netsh advfirewall firewall add rule name="%s" dir=in action=allow program="%s" enable=yes`, ProductName, fullPath)).Run()
} }
} }
+2 -2
View File
@@ -4,9 +4,9 @@ go 1.18
require ( require (
github.com/gorilla/websocket v1.4.2 github.com/gorilla/websocket v1.4.2
github.com/kardianos/service v1.2.0
github.com/lucas-clemente/quic-go v0.27.0 github.com/lucas-clemente/quic-go v0.27.0
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
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
) )
@@ -14,13 +14,13 @@ require (
github.com/cheekybits/genny v1.0.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect
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/kardianos/service v1.2.2 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/ginkgo v1.16.4 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/mobile v0.0.0-20221020085226-b36e6246172e // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.1.12 // indirect