Compare commits

..
3 Commits
Author SHA1 Message Date
TenderIronh 791d910314 3.6.5 2023-03-05 00:44:22 +08:00
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
15 changed files with 108 additions and 72 deletions
+17
View File
@@ -0,0 +1,17 @@
## Build
```
cd core
go get -v golang.org/x/mobile/bind
gomobile bind -target android -v
if [[ $? -ne 0 ]]; then
echo "build error"
exit 9
fi
echo "build ok"
cp openp2p.aar openp2p-sources.jar ../app/app/libs
echo "copy to APP libs"
cd ../app
./gradlew build
```
-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 ""
+4 -1
View File
@@ -128,10 +128,13 @@ func (c *Config) load() error {
return err return err
} }
// TODO: deal with multi-thread r/w
func (c *Config) setToken(token uint64) { func (c *Config) setToken(token uint64) {
c.mtx.Lock() c.mtx.Lock()
defer c.mtx.Unlock() defer c.mtx.Unlock()
if token != 0 {
c.Network.Token = token c.Network.Token = token
}
} }
func (c *Config) setUser(user string) { func (c *Config) setUser(user string) {
c.mtx.Lock() c.mtx.Lock()
@@ -229,7 +232,7 @@ func parseParams(subCommand string) {
gConf.Network.TCPPort = *tcpPort gConf.Network.TCPPort = *tcpPort
} }
if f.Name == "token" { if f.Name == "token" {
gConf.Network.Token = *token gConf.setToken(*token)
} }
}) })
+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,
} }
+5 -3
View File
@@ -9,6 +9,8 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"time" "time"
"github.com/openp2p-cn/totp"
) )
func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error {
@@ -40,8 +42,9 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error {
return ErrVersionNotCompatible return ErrVersionNotCompatible
} }
// verify totp token or token // verify totp token or token
if VerifyTOTP(req.Token, pn.config.Token, time.Now().Unix()+(pn.serverTs-pn.localTs)) || // localTs may behind, auto adjust ts t := totp.TOTP{Step: totp.RelayTOTPStep}
VerifyTOTP(req.Token, pn.config.Token, time.Now().Unix()) { if t.Verify(req.Token, pn.config.Token, time.Now().Unix()+(pn.serverTs-pn.localTs)) || // localTs may behind, auto adjust ts
t.Verify(req.Token, pn.config.Token, time.Now().Unix()) {
gLog.Printf(LvINFO, "Access Granted\n") gLog.Printf(LvINFO, "Access Granted\n")
config := AppConfig{} config := AppConfig{}
config.peerNatType = req.NatType config.peerNatType = req.NatType
@@ -101,7 +104,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{}
+3 -3
View File
@@ -67,11 +67,11 @@ func NewLogger(path string, filePrefix string, level LogLevel, maxLogSize int64,
os.MkdirAll(logdir, 0777) os.MkdirAll(logdir, 0777)
for lv := range logFileNames { for lv := range logFileNames {
logFilePath := logdir + filePrefix + logFileNames[lv] logFilePath := logdir + filePrefix + logFileNames[lv]
f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
os.Chmod(logFilePath, 0666) os.Chmod(logFilePath, 0644)
logfiles[lv] = f logfiles[lv] = f
loggers[lv] = log.New(f, "", log.LstdFlags) loggers[lv] = log.New(f, "", log.LstdFlags)
} }
@@ -119,7 +119,7 @@ func (l *logger) checkFile() {
backupPath := l.logDir + fname + ".0" backupPath := l.logDir + fname + ".0"
os.Remove(backupPath) os.Remove(backupPath)
os.Rename(l.logDir+fname, backupPath) os.Rename(l.logDir+fname, backupPath)
newFile, e := os.OpenFile(l.logDir+fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) newFile, e := os.OpenFile(l.logDir+fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if e == nil { if e == nil {
l.loggers[lv].SetOutput(newFile) l.loggers[lv].SetOutput(newFile)
l.files[lv] = newFile l.files[lv] = newFile
+7 -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)
@@ -53,6 +53,10 @@ func Run() {
gLog.Println(LvINFO, &gConf) gLog.Println(LvINFO, &gConf)
setFirewall() setFirewall()
err := setRLimit()
if err != nil {
gLog.Println(LvINFO, "setRLimit error:", err)
}
network := P2PNetworkInstance(&gConf.Network) network := P2PNetworkInstance(&gConf.Network)
if ok := network.Connect(30000); !ok { if ok := network.Connect(30000); !ok {
gLog.Println(LvERROR, "P2PNetwork login error") gLog.Println(LvERROR, "P2PNetwork login error")
@@ -70,7 +74,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("")
+5 -2
View File
@@ -51,7 +51,7 @@ func (app *p2pApp) listenTCP() error {
gLog.Printf(LvDEBUG, "tcp accept on port %d start", app.config.SrcPort) gLog.Printf(LvDEBUG, "tcp accept on port %d start", app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "tcp accept on port %d end", app.config.SrcPort) defer gLog.Printf(LvDEBUG, "tcp accept on port %d end", app.config.SrcPort)
var err error var err error
app.listener, err = net.Listen("tcp4", fmt.Sprintf("0.0.0.0:%d", app.config.SrcPort)) app.listener, err = net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", app.config.SrcPort)) // support tcp4 and tcp6
if err != nil { if err != nil {
gLog.Printf(LvERROR, "listen error:%s", err) gLog.Printf(LvERROR, "listen error:%s", err)
return err return err
@@ -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
+16 -14
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"
@@ -28,7 +27,7 @@ type P2PNetwork struct {
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
@@ -73,8 +72,7 @@ func (pn *P2PNetwork) run() {
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)
@@ -129,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
@@ -155,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")
} }
@@ -371,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")
@@ -417,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 {
@@ -440,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")
pn.wgReconnect.Add(1)
go func() { //reconnect at least 5s
time.Sleep(NatTestTimeout)
pn.wgReconnect.Done()
}()
var err error var err error
for { for {
// detect nat type // detect nat type
@@ -490,7 +490,7 @@ func (pn *P2PNetwork) init() error {
go pn.readLoop() 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,
@@ -511,6 +511,7 @@ func (pn *P2PNetwork) init() error {
} }
req.IPv6 = pn.config.publicIPv6 req.IPv6 = pn.config.publicIPv6
pn.write(MsgReport, MsgReportBasic, &req) pn.write(MsgReport, MsgReportBasic, &req)
}()
gLog.Println(LvDEBUG, "P2PNetwork init ok") gLog.Println(LvDEBUG, "P2PNetwork init ok")
break break
} }
@@ -550,6 +551,7 @@ func (pn *P2PNetwork) handleMessage(t int, msg []byte) {
gConf.setUser(rsp.User) gConf.setUser(rsp.User)
if len(rsp.Node) >= MinNodeNameLen { if len(rsp.Node) >= MinNodeNameLen {
gConf.setNode(rsp.Node) gConf.setNode(rsp.Node)
pn.config.Node = rsp.Node
} }
gConf.save() gConf.save()
pn.localTs = time.Now().Unix() pn.localTs = time.Now().Unix()
@@ -571,8 +573,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.2" const OpenP2PVersion = "3.6.5"
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
) )
+1 -1
View File
@@ -21,7 +21,7 @@ func setRLimit() error {
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
return err return err
} }
limit.Cur = 10240 limit.Cur = 65536
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
return err return err
} }
+1 -1
View File
@@ -64,7 +64,7 @@ func setRLimit() error {
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
return err return err
} }
limit.Max = 1024 * 1024 limit.Max = 65536
limit.Cur = limit.Max limit.Cur = limit.Max
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
return err return err
+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()
} }
} }
+4 -1
View File
@@ -4,9 +4,10 @@ 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
github.com/openp2p-cn/totp v0.0.0-20230102121327-8e02f6b392ed
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
) )
@@ -14,6 +15,7 @@ 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
@@ -23,5 +25,6 @@ require (
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
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
) )