This commit is contained in:
TenderIronh
2025-11-13 17:57:49 +08:00
parent 4daeeaab1a
commit d827fd108d
11 changed files with 207 additions and 121 deletions
+1 -2
View File
@@ -174,7 +174,7 @@ func (c *Config) retryApp(peerNode string) {
app.hbMtx.Unlock() app.hbMtx.Unlock()
} }
if app.config.RelayNode == peerNode { if app.config.RelayNode == peerNode {
gLog.Println(LvDEBUG, "retry app ", app.config.LogPeerNode()) gLog.Println(LvDEBUG, "retry app relay=", app.config.LogPeerNode())
app.retryRelayNum = 0 app.retryRelayNum = 0
app.nextRetryRelayTime = time.Now() app.nextRetryRelayTime = time.Now()
app.hbMtx.Lock() app.hbMtx.Lock()
@@ -423,7 +423,6 @@ func parseParams(subCommand string, cmd string) {
fset.Parse(os.Args[2:]) fset.Parse(os.Args[2:])
} }
} else { } else {
gLog.Println(LvINFO, "cmd=", cmd)
args := strings.Split(cmd, " ") args := strings.Split(cmd, " ")
fset.Parse(args) fset.Parse(args)
} }
+3 -9
View File
@@ -1,7 +1,6 @@
package openp2p package openp2p
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
@@ -15,12 +14,12 @@ type daemon struct {
} }
func (d *daemon) Start(s service.Service) error { func (d *daemon) Start(s service.Service) error {
gLog.Println(LvINFO, "daemon start") gLog.Println(LvINFO, "system service start")
return nil return nil
} }
func (d *daemon) Stop(s service.Service) error { func (d *daemon) Stop(s service.Service) error {
gLog.Println(LvINFO, "service stop") gLog.Println(LvINFO, "system service stop")
d.running = false d.running = false
if d.proc != nil { if d.proc != nil {
gLog.Println(LvINFO, "stop worker") gLog.Println(LvINFO, "stop worker")
@@ -38,11 +37,6 @@ func (d *daemon) run() {
defer gLog.Println(LvINFO, "daemon run end") defer gLog.Println(LvINFO, "daemon run end")
d.running = true d.running = true
binPath, _ := os.Executable() binPath, _ := os.Executable()
mydir, err := os.Getwd()
if err != nil {
fmt.Println(err)
}
gLog.Println(LvINFO, mydir)
conf := &service.Config{ conf := &service.Config{
Name: ProductName, Name: ProductName,
DisplayName: ProductName, DisplayName: ProductName,
@@ -68,7 +62,7 @@ func (d *daemon) run() {
dumpFile := filepath.Join("log", "dump.log") dumpFile := filepath.Join("log", "dump.log")
f, err := os.Create(filepath.Join(tmpDump)) f, err := os.Create(filepath.Join(tmpDump))
if err != nil { if err != nil {
gLog.Printf(LvERROR, "start worker error:%s", err) gLog.Printf(LvERROR, "create file %s error:%s", tmpDump, err)
return return
} }
gLog.Println(LvINFO, "start worker process, args:", args) gLog.Println(LvINFO, "start worker process, args:", args)
+16 -18
View File
@@ -28,7 +28,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushRsp: case MsgPushRsp:
rsp := PushRsp{} rsp := PushRsp{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &rsp); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &rsp); err != nil {
gLog.Printf(LvERROR, "wrong pushRsp:%s", err) gLog.Printf(LvERROR, "Unmarshal pushRsp:%s", err)
return err return err
} }
if rsp.Error == 0 { if rsp.Error == 0 {
@@ -39,7 +39,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushAddRelayTunnelReq: case MsgPushAddRelayTunnelReq:
req := AddRelayTunnelReq{} req := AddRelayTunnelReq{}
if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s", reflect.TypeOf(req), err) gLog.Printf(LvERROR, "Unmarshal %v:%s", reflect.TypeOf(req), err)
return err return err
} }
config := AppConfig{} config := AppConfig{}
@@ -62,7 +62,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushServerSideSaveMemApp: case MsgPushServerSideSaveMemApp:
req := ServerSideSaveMemApp{} req := ServerSideSaveMemApp{}
if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s", reflect.TypeOf(req), err) gLog.Printf(LvERROR, "Unmarshal %v:%s", reflect.TypeOf(req), err)
return err return err
} }
gLog.Println(LvDEBUG, "handle MsgPushServerSideSaveMemApp:", prettyJson(req)) gLog.Println(LvDEBUG, "handle MsgPushServerSideSaveMemApp:", prettyJson(req))
@@ -91,7 +91,7 @@ func handlePush(subType uint16, msg []byte) error {
} else { } else {
app.setRelayTunnel(existTunnel) app.setRelayTunnel(existTunnel)
} }
gLog.Println(LvDEBUG, "find existing memapp, update it") gLog.Println(LvDEBUG, "found existing memapp, update it")
} else { } else {
appConfig := existTunnel.config appConfig := existTunnel.config
appConfig.SrcPort = 0 appConfig.SrcPort = 0
@@ -121,7 +121,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushAPPKey: case MsgPushAPPKey:
req := APPKeySync{} req := APPKeySync{}
if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s", reflect.TypeOf(req), err) gLog.Printf(LvERROR, "Unmarshal %v:%s", reflect.TypeOf(req), err)
return err return err
} }
SaveKey(req.AppID, req.AppKey) SaveKey(req.AppID, req.AppKey)
@@ -152,7 +152,7 @@ func handlePush(subType uint16, msg []byte) error {
gLog.Println(LvINFO, "MsgPushEditNode") gLog.Println(LvINFO, "MsgPushEditNode")
req := EditNode{} req := EditNode{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
gConf.setNode(req.NewName) gConf.setNode(req.NewName)
@@ -162,7 +162,7 @@ func handlePush(subType uint16, msg []byte) error {
gLog.Println(LvINFO, "MsgPushSwitchApp") gLog.Println(LvINFO, "MsgPushSwitchApp")
app := AppInfo{} app := AppInfo{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &app); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &app); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(app), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(app), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
config := AppConfig{Enabled: app.Enabled, SrcPort: app.SrcPort, Protocol: app.Protocol} config := AppConfig{Enabled: app.Enabled, SrcPort: app.SrcPort, Protocol: app.Protocol}
@@ -173,13 +173,12 @@ func handlePush(subType uint16, msg []byte) error {
GNetwork.DeleteApp(config) GNetwork.DeleteApp(config)
} }
case MsgPushDstNodeOnline: case MsgPushDstNodeOnline:
gLog.Println(LvINFO, "MsgPushDstNodeOnline")
req := PushDstNodeOnline{} req := PushDstNodeOnline{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
gLog.Println(LvINFO, "retry peerNode ", req.Node) gLog.Printf(LvINFO, "%s online, retryApp", req.Node)
gConf.retryApp(req.Node) gConf.retryApp(req.Node)
default: default:
i, ok := GNetwork.msgMap.Load(pushHead.From) i, ok := GNetwork.msgMap.Load(pushHead.From)
@@ -196,7 +195,7 @@ func handleEditApp(msg []byte) (err error) {
gLog.Println(LvINFO, "MsgPushEditApp") gLog.Println(LvINFO, "MsgPushEditApp")
newApp := AppInfo{} newApp := AppInfo{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &newApp); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &newApp); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(newApp), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(newApp), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
oldConf := AppConfig{Enabled: 1} oldConf := AppConfig{Enabled: 1}
@@ -228,11 +227,10 @@ func handleEditApp(msg []byte) (err error) {
func handleConnectReq(msg []byte) (err error) { func handleConnectReq(msg []byte) (err error) {
req := PushConnectReq{} req := PushConnectReq{}
if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s", reflect.TypeOf(req), err) gLog.Printf(LvERROR, "Unmarshal %v:%s", reflect.TypeOf(req), err)
return err return err
} }
gLog.Printf(LvDEBUG, "%s is connecting...", req.From) gLog.Printf(LvDEBUG, "%s is connecting... push connect response", req.From)
gLog.Println(LvDEBUG, "push connect response to ", req.From)
if compareVersion(req.Version, LeastSupportVersion) < 0 { if compareVersion(req.Version, LeastSupportVersion) < 0 {
gLog.Println(LvERROR, ErrVersionNotCompatible.Error(), ":", req.From) gLog.Println(LvERROR, ErrVersionNotCompatible.Error(), ":", req.From)
rsp := PushConnectRsp{ rsp := PushConnectRsp{
@@ -247,7 +245,7 @@ func handleConnectReq(msg []byte) (err error) {
// verify totp token or token // verify totp token or token
t := totp.TOTP{Step: totp.RelayTOTPStep} t := totp.TOTP{Step: totp.RelayTOTPStep}
if t.Verify(req.Token, gConf.Network.Token, time.Now().Unix()-GNetwork.dt/int64(time.Second)) { // localTs may behind, auto adjust ts if t.Verify(req.Token, gConf.Network.Token, time.Now().Unix()-GNetwork.dt/int64(time.Second)) { // localTs may behind, auto adjust ts
gLog.Printf(LvINFO, "Access Granted") gLog.Printf(LvINFO, "handleConnectReq Access Granted")
config := AppConfig{} config := AppConfig{}
config.peerNatType = req.NatType config.peerNatType = req.NatType
config.peerConeNatPort = req.ConeNatPort config.peerConeNatPort = req.ConeNatPort
@@ -272,7 +270,7 @@ func handleConnectReq(msg []byte) (err error) {
}() }()
return nil return nil
} }
gLog.Println(LvERROR, "Access Denied:", req.From) gLog.Println(LvERROR, "handleConnectReq Access Denied:", req.From)
rsp := PushConnectRsp{ rsp := PushConnectRsp{
Error: 1, Error: 1,
Detail: fmt.Sprintf("connect to %s error: Access Denied", gConf.Network.Node), Detail: fmt.Sprintf("connect to %s error: Access Denied", gConf.Network.Node),
@@ -412,7 +410,7 @@ func handleLog(msg []byte) (err error) {
const maxLen = 1024 * 1024 const maxLen = 1024 * 1024
req := ReportLogReq{} req := ReportLogReq{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
if req.FileName == "" { if req.FileName == "" {
@@ -467,7 +465,7 @@ func handleCheckRemoteService(msg []byte) (err error) {
gLog.Println(LvDEBUG, "handleCheckRemoteService") gLog.Println(LvDEBUG, "handleCheckRemoteService")
req := CheckRemoteService{} req := CheckRemoteService{}
if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil { if err = json.Unmarshal(msg[openP2PHeaderSize:], &req); err != nil {
gLog.Printf(LvERROR, "wrong %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:])) gLog.Printf(LvERROR, "Unmarshal %v:%s %s", reflect.TypeOf(req), err, string(msg[openP2PHeaderSize:]))
return err return err
} }
rsp := PushRsp{Error: 0} rsp := PushRsp{Error: 0}
+30 -31
View File
@@ -39,19 +39,19 @@ func handshakeC2C(t *P2PTunnel) (err error) {
tunnelID = t.id tunnelID = t.id
} }
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 tunnelid:%d handshake ", t.id)
UDPWrite(conn, t.remoteHoleAddr, 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)
return err return err
} }
} }
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 tunnelID:%d handshake ack ", t.id)
_, err = UDPWrite(conn, t.remoteHoleAddr, 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
} }
} }
@@ -60,8 +60,8 @@ func handshakeC2C(t *P2PTunnel) (err error) {
} }
func handshakeC2S(t *P2PTunnel) error { func handshakeC2S(t *P2PTunnel) error {
gLog.Printf(LvDEBUG, "handshakeC2S start") gLog.Printf(LvDEBUG, "tid:%d handshakeC2S start", t.id)
defer gLog.Printf(LvDEBUG, "handshakeC2S end") defer gLog.Printf(LvDEBUG, "tid:%d handshakeC2S end", t.id)
if !buildTunnelMtx.TryLock() { if !buildTunnelMtx.TryLock() {
// time.Sleep(time.Second * 3) // time.Sleep(time.Second * 3)
return ErrBuildTunnelBusy return ErrBuildTunnelBusy
@@ -77,7 +77,7 @@ func handshakeC2S(t *P2PTunnel) error {
defer conn.Close() defer conn.Close()
go func() error { go func() error {
gLog.Printf(LvDEBUG, "send symmetric handshake to %s from %d:%d start", t.config.peerIP, t.coneLocalPort, t.coneNatPort) gLog.Printf(LvDEBUG, "tid:%d send symmetric handshake to %s from %d:%d start", t.id, t.config.peerIP, t.coneLocalPort, t.coneNatPort)
for i := 0; i < SymmetricHandshakeNum; i++ { for i := 0; i < SymmetricHandshakeNum; i++ {
// time.Sleep(SymmetricHandshakeInterval) // time.Sleep(SymmetricHandshakeInterval)
dst, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", t.config.peerIP, randPorts[i]+2)) dst, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", t.config.peerIP, randPorts[i]+2))
@@ -86,29 +86,29 @@ func handshakeC2S(t *P2PTunnel) error {
} }
_, err = UDPWrite(conn, dst, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id}) _, err = UDPWrite(conn, dst, MsgP2P, MsgPunchHandshake, P2PHandshakeReq{ID: t.id})
if err != nil { if err != nil {
gLog.Println(LvDEBUG, "handshakeC2S write MsgPunchHandshake error:", err) gLog.Printf(LvDEBUG, "tid:%d handshakeC2S write MsgPunchHandshake error:%s", t.id, err)
return err return err
} }
} }
gLog.Println(LvDEBUG, "send symmetric handshake end") gLog.Printf(LvDEBUG, "tid:%d send symmetric handshake end", t.id)
return nil return nil
}() }()
err = conn.SetReadDeadline(time.Now().Add(HandshakeTimeout)) err = conn.SetReadDeadline(time.Now().Add(HandshakeTimeout))
if err != nil { if err != nil {
gLog.Println(LvERROR, "SymmetricHandshakeAckTimeout SetReadDeadline error") gLog.Println(LvERROR, "tid:%d SymmetricHandshakeAckTimeout SetReadDeadline error", t.id)
return err return err
} }
// read response of the punching hole ok port // read response of the punching hole ok port
buff := make([]byte, 1024) buff := make([]byte, 1024)
_, dst, err := conn.ReadFrom(buff) _, dst, err := conn.ReadFrom(buff)
if err != nil { if err != nil {
gLog.Println(LvERROR, "handshakeC2S wait timeout") gLog.Println(LvERROR, "tid:%d handshakeC2S wait timeout", t.id)
return err return err
} }
head := &openP2PHeader{} head := &openP2PHeader{}
err = binary.Read(bytes.NewReader(buff[:openP2PHeaderSize]), binary.LittleEndian, head) err = binary.Read(bytes.NewReader(buff[:openP2PHeaderSize]), binary.LittleEndian, head)
if err != nil { if err != nil {
gLog.Println(LvERROR, "parse p2pheader error:", err) gLog.Printf(LvERROR, "tid:%d parse p2pheader error:%s", t.id, err)
return err return err
} }
t.remoteHoleAddr, _ = net.ResolveUDPAddr("udp", dst.String()) t.remoteHoleAddr, _ = net.ResolveUDPAddr("udp", dst.String())
@@ -122,12 +122,12 @@ func handshakeC2S(t *P2PTunnel) error {
tunnelID = t.id tunnelID = t.id
} }
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, "tid:%d handshakeC2S read handshake ", t.id)
UDPWrite(conn, t.remoteHoleAddr, 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 {
gLog.Println(LvDEBUG, "handshakeC2S handshake error") gLog.Printf(LvDEBUG, "tid:%d handshakeC2S handshake error", t.id)
return err return err
} }
var tunnelID uint64 var tunnelID uint64
@@ -146,19 +146,19 @@ 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.remoteHoleAddr.String()) gLog.Printf(LvDEBUG, "tid:%d handshakeC2S read handshake ack %s", t.id, t.remoteHoleAddr.String())
_, err = UDPWrite(conn, t.remoteHoleAddr, 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.Printf(LvDEBUG, "tid:%d handshakeS2C read msg but not MsgPunchHandshakeAck", t.id)
} }
gLog.Printf(LvINFO, "handshakeC2S ok. cost %d ms", time.Since(startTime)/time.Millisecond) gLog.Printf(LvINFO, "tid:%d handshakeC2S ok. cost %d ms", t.id, time.Since(startTime)/time.Millisecond)
return nil return nil
} }
func handshakeS2C(t *P2PTunnel) error { func handshakeS2C(t *P2PTunnel) error {
gLog.Printf(LvDEBUG, "handshakeS2C start") gLog.Printf(LvDEBUG, "tid:%d handshakeS2C start", t.id)
defer gLog.Printf(LvDEBUG, "handshakeS2C end") defer gLog.Printf(LvDEBUG, "tid:%d handshakeS2C end", t.id)
if !buildTunnelMtx.TryLock() { if !buildTunnelMtx.TryLock() {
// time.Sleep(time.Second * 3) // time.Sleep(time.Second * 3)
return ErrBuildTunnelBusy return ErrBuildTunnelBusy
@@ -167,14 +167,14 @@ func handshakeS2C(t *P2PTunnel) error {
startTime := time.Now() startTime := time.Now()
gotCh := make(chan *net.UDPAddr, 5) gotCh := make(chan *net.UDPAddr, 5)
// sequencely udp send handshake, do not parallel send // sequencely udp send handshake, do not parallel send
gLog.Printf(LvDEBUG, "send symmetric handshake to %s:%d start", t.config.peerIP, t.config.peerConeNatPort) gLog.Printf(LvDEBUG, "tid:%d send symmetric handshake to %s:%d start", t.id, t.config.peerIP, t.config.peerConeNatPort)
gotIt := false gotIt := false
for i := 0; i < SymmetricHandshakeNum; i++ { for i := 0; i < SymmetricHandshakeNum; i++ {
// time.Sleep(SymmetricHandshakeInterval) // time.Sleep(SymmetricHandshakeInterval)
go func(t *P2PTunnel) error { go func(t *P2PTunnel) error {
conn, err := net.ListenUDP("udp", nil) // TODO: system allocated port really random? conn, err := net.ListenUDP("udp", nil) // TODO: system allocated port really random?
if err != nil { if err != nil {
gLog.Printf(LvDEBUG, "listen error") gLog.Printf(LvDEBUG, "tid:%d listen error", t.id)
return err return err
} }
defer conn.Close() defer conn.Close()
@@ -198,13 +198,13 @@ 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, "tid:%d handshakeS2C read handshake ", t.id)
UDPWrite(conn, t.remoteHoleAddr, 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)
if err != nil { if err != nil {
gLog.Println(LvDEBUG, "handshakeS2C handshake error") gLog.Println(LvDEBUG, "tid:%d handshakeS2C handshake error", t.id)
return err return err
} }
if len(buff) > openP2PHeaderSize { if len(buff) > openP2PHeaderSize {
@@ -218,36 +218,35 @@ func handshakeS2C(t *P2PTunnel) error {
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck && tunnelID == t.id { if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck && tunnelID == t.id {
break break
} else { } else {
gLog.Println(LvDEBUG, "handshakeS2C read msg but not MsgPunchHandshakeAck") gLog.Println(LvDEBUG, "tid:%d handshakeS2C read msg but not MsgPunchHandshakeAck", t.id)
} }
} }
} }
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, "tid:%d handshakeS2C read handshake ack %s", t.id, conn.LocalAddr().String())
UDPWrite(conn, t.remoteHoleAddr, 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
return nil return nil
} else { } else {
gLog.Println(LvDEBUG, "handshakeS2C read msg but not MsgPunchHandshakeAck") gLog.Printf(LvDEBUG, "tid:%d handshakeS2C read msg but not MsgPunchHandshakeAck", t.id)
} }
return nil return nil
}(t) }(t)
} }
gLog.Printf(LvDEBUG, "send symmetric handshake end") gLog.Printf(LvDEBUG, "tid:%d send symmetric handshake end", t.id)
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.Printf(LvDEBUG, "tid:%d handshakeS2C ready, notify peer connect", t.id)
GNetwork.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("tid:%d wait handshake timeout", t.id)
case la := <-gotCh: case la := <-gotCh:
t.localHoleAddr = la t.localHoleAddr = la
gLog.Println(LvDEBUG, "symmetric handshake ok", la) gLog.Printf(LvINFO, "tid:%d handshakeS2C ok. cost %dms", t.id, time.Since(startTime)/time.Millisecond)
gLog.Printf(LvINFO, "handshakeS2C ok. cost %dms", time.Since(startTime)/time.Millisecond)
} }
return nil return nil
} }
+2 -3
View File
@@ -24,7 +24,7 @@ func install() {
} }
err = os.Chdir(defaultInstallPath) err = os.Chdir(defaultInstallPath)
if err != nil { if err != nil {
gLog.Println(LvERROR, "cd error:", err) gLog.Println(LvERROR, "Chdir error:", err)
return return
} }
@@ -38,7 +38,7 @@ func install() {
binPath, _ := os.Executable() binPath, _ := os.Executable()
src, errFiles := os.Open(binPath) // can not use args[0], on Windows call openp2p is ok(=openp2p.exe) src, errFiles := os.Open(binPath) // can not use args[0], on Windows call openp2p is ok(=openp2p.exe)
if errFiles != nil { if errFiles != nil {
gLog.Printf(LvERROR, "os.OpenFile %s error:%s", os.Args[0], errFiles) gLog.Printf(LvERROR, "os.Open %s error:%s", os.Args[0], errFiles)
return return
} }
@@ -57,7 +57,6 @@ func install() {
dst.Close() dst.Close()
// install system service // install system service
gLog.Println(LvINFO, "targetPath:", targetPath)
err = d.Control("install", targetPath, []string{"-d"}) err = d.Control("install", targetPath, []string{"-d"})
if err == nil { if err == nil {
gLog.Println(LvINFO, "install system service ok.") gLog.Println(LvINFO, "install system service ok.")
+2 -2
View File
@@ -41,7 +41,7 @@ func Run() {
return return
} }
gLog.Println(LvINFO, &gConf) gLog.Printf(LvINFO, "node=%s, serverHost=%s, serverPort=%d", gConf.Network.Node, gConf.Network.ServerHost, gConf.Network.ServerPort)
setFirewall() setFirewall()
err := setRLimit() err := setRLimit()
if err != nil { if err != nil {
@@ -78,7 +78,7 @@ func RunAsModule(baseDir string, token string, bw int, logLevel int) *P2PNetwork
gConf.setShareBandwidth(bw) gConf.setShareBandwidth(bw)
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion) gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
gLog.Println(LvINFO, "Contact: QQ group 16947733, Email [email protected]") gLog.Println(LvINFO, "Contact: QQ group 16947733, Email [email protected]")
gLog.Println(LvINFO, &gConf) gLog.Printf(LvINFO, "node=%s, serverHost=%s, serverPort=%d", gConf.Network.Node, gConf.Network.ServerHost, gConf.Network.ServerPort)
GNetwork = P2PNetworkInstance() GNetwork = P2PNetworkInstance()
if ok := GNetwork.Connect(30000); !ok { if ok := GNetwork.Connect(30000); !ok {
+104 -13
View File
@@ -3,40 +3,131 @@
package openp2p package openp2p
import "github.com/openp2p-cn/wireguard-go/tun" import (
"fmt"
"net"
"os/exec"
"strings"
"github.com/openp2p-cn/wireguard-go/tun"
"github.com/vishvananda/netlink"
)
const ( const (
tunIfaceName = "optun" tunIfaceName = "optun"
PIHeaderSize = 0 PIHeaderSize = 0
) )
var previousIP = ""
func (t *optun) Start(localAddr string, detail *SDWANInfo) error { func (t *optun) Start(localAddr string, detail *SDWANInfo) error {
var err error var err error
t.tunName = tunIfaceName t.tunName = tunIfaceName
t.dev, err = tun.CreateTUN(t.tunName, 1420) t.dev, err = tun.CreateTUN(t.tunName, 1420)
if err != nil { if err != nil {
return err return err
} }
err = setTunAddr(t.tunName, localAddr, detail.Gateway, t.dev)
if err != nil {
return err
}
return nil return nil
} }
func (t *optun) Read(bufs [][]byte, sizes []int, offset int) (n int, err error) {
return t.dev.Read(bufs, sizes, offset)
}
func (t *optun) Write(bufs [][]byte, offset int) (int, error) {
return t.dev.Write(bufs, offset)
}
func setTunAddr(ifname, localAddr, remoteAddr string, wintun interface{}) error {
ifce, err := netlink.LinkByName(ifname)
if err != nil {
return err
}
netlink.LinkSetMTU(ifce, 1375)
netlink.LinkSetTxQLen(ifce, 100)
netlink.LinkSetUp(ifce)
ln, err := netlink.ParseIPNet(localAddr)
if err != nil {
return err
}
ln.Mask = net.CIDRMask(32, 32)
rn, err := netlink.ParseIPNet(remoteAddr)
if err != nil {
return err
}
rn.Mask = net.CIDRMask(32, 32)
addr := &netlink.Addr{
IPNet: ln,
Peer: rn,
}
if previousIP != "" {
lnDel, err := netlink.ParseIPNet(previousIP)
if err != nil {
return err
}
lnDel.Mask = net.CIDRMask(32, 32)
addrDel := &netlink.Addr{
IPNet: lnDel,
Peer: rn,
}
netlink.AddrDel(ifce, addrDel)
}
previousIP = localAddr
return netlink.AddrAdd(ifce, addr)
}
func addRoute(dst, gw, ifname string) error { func addRoute(dst, gw, ifname string) error {
return nil _, networkid, err := net.ParseCIDR(dst)
if err != nil {
return err
}
ipGW := net.ParseIP(gw)
if ipGW == nil {
return fmt.Errorf("parse gateway %s failed", gw)
}
route := &netlink.Route{
Dst: networkid,
Gw: ipGW,
}
return netlink.RouteAdd(route)
} }
func delRoute(dst, gw string) error { func delRoute(dst, gw string) error {
return nil _, networkid, err := net.ParseCIDR(dst)
} if err != nil {
func addTunAddr(localAddr, remoteAddr string) error { return err
return nil }
route := &netlink.Route{
Dst: networkid,
}
return netlink.RouteDel(route)
} }
func delTunAddr(localAddr, remoteAddr string) error { func delRoutesByGateway(gateway string) error {
cmd := exec.Command("route", "-n")
output, err := cmd.Output()
if err != nil {
return err
}
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if !strings.Contains(line, gateway) {
continue
}
fields := strings.Fields(line)
if len(fields) >= 8 && fields[1] == "0.0.0.0" && fields[7] == gateway {
delCmd := exec.Command("route", "del", "-net", fields[0], "gw", gateway)
err := delCmd.Run()
if err != nil {
gLog.Printf(LvERROR, "Delete route %s error:%s", fields[0], err)
continue
}
gLog.Printf(LvINFO, "Delete route ok: %s %s %s\n", fields[0], fields[1], gateway)
}
}
return nil return nil
} }
+5 -5
View File
@@ -41,8 +41,8 @@ type overlayConn struct {
} }
func (oConn *overlayConn) run() { func (oConn *overlayConn) run() {
gLog.Printf(LvDEBUG, "%d overlayConn run start", oConn.id) gLog.Printf(LvDEBUG, "oid:%d overlayConn run start", oConn.id)
defer gLog.Printf(LvDEBUG, "%d overlayConn run end", oConn.id) defer gLog.Printf(LvDEBUG, "oid:%d overlayConn run end", oConn.id)
oConn.lastReadUDPTs = time.Now() oConn.lastReadUDPTs = time.Now()
buffer := make([]byte, ReadBuffLen+PaddingSize) // 16 bytes for padding buffer := make([]byte, ReadBuffLen+PaddingSize) // 16 bytes for padding
reuseBuff := buffer[:ReadBuffLen] reuseBuff := buffer[:ReadBuffLen]
@@ -58,7 +58,7 @@ func (oConn *overlayConn) run() {
continue continue
} }
// overlay tcp connection normal close, debug log // overlay tcp connection normal close, debug log
gLog.Printf(LvDEBUG, "overlayConn %d read error:%s,close it", oConn.id, err) gLog.Printf(LvDEBUG, "oid:%d overlayConn read error:%s,close it", oConn.id, err)
break break
} }
payload := readBuff[:dataLen] payload := readBuff[:dataLen]
@@ -69,13 +69,13 @@ func (oConn *overlayConn) run() {
// TODO: app.write // TODO: app.write
if oConn.rtid == 0 { if oConn.rtid == 0 {
oConn.tunnel.conn.WriteBytes(MsgP2P, MsgOverlayData, writeBytes) oConn.tunnel.conn.WriteBytes(MsgP2P, MsgOverlayData, writeBytes)
gLog.Printf(LvDev, "write overlay data to tid:%d,oid:%d bodylen=%d", oConn.tunnel.id, oConn.id, len(writeBytes)) gLog.Printf(LvDev, "oid:%d write overlay data to tid:%d bodylen=%d", oConn.id, oConn.tunnel.id, oConn.id, len(writeBytes))
} else { } else {
// write raley data // write raley data
all := append(relayHead.Bytes(), encodeHeader(MsgP2P, MsgOverlayData, uint32(len(writeBytes)))...) all := append(relayHead.Bytes(), encodeHeader(MsgP2P, MsgOverlayData, uint32(len(writeBytes)))...)
all = append(all, writeBytes...) all = append(all, writeBytes...)
oConn.tunnel.conn.WriteBytes(MsgP2P, MsgRelayData, all) oConn.tunnel.conn.WriteBytes(MsgP2P, MsgRelayData, all)
gLog.Printf(LvDev, "write relay data to tid:%d,rtid:%d,oid:%d bodylen=%d", oConn.tunnel.id, oConn.rtid, oConn.id, len(writeBytes)) gLog.Printf(LvDev, "oid:%d write relay data to tid:%d,rtid:%d bodylen=%d", oConn.id, oConn.tunnel.id, oConn.rtid, len(writeBytes))
} }
} }
if oConn.connTCP != nil { if oConn.connTCP != nil {
+31 -31
View File
@@ -138,7 +138,7 @@ func (app *p2pApp) checkDirectTunnel() error {
app.config.retryNum = 1 app.config.retryNum = 1
} }
if app.config.retryNum > 0 { // first time not show reconnect log if app.config.retryNum > 0 { // first time not show reconnect log
gLog.Printf(LvINFO, "detect app %s appid:%d disconnect, reconnecting the %d times...", app.config.LogPeerNode(), app.id, app.config.retryNum) gLog.Printf(LvINFO, "appid:%d checkDirectTunnel detect peer %s disconnect, reconnecting the %d times...", app.id, app.config.LogPeerNode(), app.config.retryNum)
} }
app.config.retryNum++ app.config.retryNum++
app.config.retryTime = time.Now() app.config.retryTime = time.Now()
@@ -149,7 +149,7 @@ func (app *p2pApp) checkDirectTunnel() error {
app.config.errMsg = err.Error() app.config.errMsg = err.Error()
if err == ErrPeerOffline && app.config.retryNum > 2 { // stop retry, waiting for online if err == ErrPeerOffline && app.config.retryNum > 2 { // stop retry, waiting for online
app.config.retryNum = retryLimit app.config.retryNum = retryLimit
gLog.Printf(LvINFO, " %s offline, it will auto reconnect when peer node online", app.config.LogPeerNode()) gLog.Printf(LvINFO, "appid:%d checkDirectTunnel %s offline, it will auto reconnect when peer node online", app.id, app.config.LogPeerNode())
} }
if err == ErrBuildTunnelBusy { if err == ErrBuildTunnelBusy {
app.config.retryNum-- app.config.retryNum--
@@ -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 requestPeerInfo error:%s", app.config.LogPeerNode(), initErr) gLog.Printf(LvERROR, "appid:%d buildDirectTunnel %s requestPeerInfo error:%s", app.id, app.config.LogPeerNode(), initErr)
return initErr return initErr
} }
t, err = pn.addDirectTunnel(app.config, 0) t, err = pn.addDirectTunnel(app.config, 0)
@@ -212,7 +212,7 @@ func (app *p2pApp) buildDirectTunnel() error {
AppID: app.id, AppID: app.id,
AppKey: app.key, AppKey: app.key,
} }
gLog.Printf(LvDEBUG, "sync appkey direct to %s", app.config.LogPeerNode()) gLog.Printf(LvDEBUG, "appid:%d buildDirectTunnel sync appkey to %s", app.id, app.config.LogPeerNode())
pn.push(app.config.PeerNode, MsgPushAPPKey, &syncKeyReq) pn.push(app.config.PeerNode, MsgPushAPPKey, &syncKeyReq)
app.setDirectTunnel(t) app.setDirectTunnel(t)
@@ -220,9 +220,9 @@ func (app *p2pApp) buildDirectTunnel() error {
if app.config.SrcPort == 0 { if app.config.SrcPort == 0 {
req := ServerSideSaveMemApp{From: gConf.Network.Node, Node: gConf.Network.Node, TunnelID: t.id, RelayTunnelID: 0, AppID: app.id} req := ServerSideSaveMemApp{From: gConf.Network.Node, Node: gConf.Network.Node, TunnelID: t.id, RelayTunnelID: 0, AppID: app.id}
pn.push(app.config.PeerNode, MsgPushServerSideSaveMemApp, &req) pn.push(app.config.PeerNode, MsgPushServerSideSaveMemApp, &req)
gLog.Printf(LvDEBUG, "push %s ServerSideSaveMemApp: %s", app.config.LogPeerNode(), prettyJson(req)) gLog.Printf(LvDEBUG, "appid:%d buildDirectTunnel push %s ServerSideSaveMemApp: %s", app.id, app.config.LogPeerNode(), prettyJson(req))
} }
gLog.Printf(LvDEBUG, "%s use tunnel %d", app.config.AppName, t.id) gLog.Printf(LvDEBUG, "appid:%d buildDirectTunnel ok. %s use tid %d", app.id, app.config.AppName, t.id)
return nil return nil
} }
@@ -244,7 +244,7 @@ func (app *p2pApp) checkRelayTunnel() error {
app.retryRelayNum = 1 app.retryRelayNum = 1
} }
if app.retryRelayNum > 0 { // first time not show reconnect log if app.retryRelayNum > 0 { // first time not show reconnect log
gLog.Printf(LvINFO, "detect app %s appid:%d relay disconnect, reconnecting the %d times...", app.config.LogPeerNode(), app.id, app.retryRelayNum) gLog.Printf(LvINFO, "appid:%d checkRelayTunnel detect peer %s relay disconnect, reconnecting the %d times...", app.id, app.config.LogPeerNode(), app.retryRelayNum)
} }
app.setRelayTunnel(nil) // reset relayTunnel app.setRelayTunnel(nil) // reset relayTunnel
app.retryRelayNum++ app.retryRelayNum++
@@ -256,7 +256,7 @@ func (app *p2pApp) checkRelayTunnel() error {
app.errMsg = err.Error() app.errMsg = err.Error()
if err == ErrPeerOffline && app.retryRelayNum > 2 { // stop retry, waiting for online if err == ErrPeerOffline && app.retryRelayNum > 2 { // stop retry, waiting for online
app.retryRelayNum = retryLimit app.retryRelayNum = retryLimit
gLog.Printf(LvINFO, " %s offline, it will auto reconnect when peer node online", app.config.LogPeerNode()) gLog.Printf(LvINFO, "appid:%d checkRelayTunnel %s offline, it will auto reconnect when peer node online", app.id, app.config.LogPeerNode())
} }
} }
if app.Tunnel() != nil { if app.Tunnel() != nil {
@@ -282,7 +282,7 @@ func (app *p2pApp) buildRelayTunnel() error {
config := app.config config := app.config
initErr := pn.requestPeerInfo(&config) initErr := pn.requestPeerInfo(&config)
if initErr != nil { if initErr != nil {
gLog.Printf(LvERROR, "%s init error:%s", config.LogPeerNode(), initErr) gLog.Printf(LvERROR, "appid:%d buildRelayTunnel %s init error:%s", app.id, config.LogPeerNode(), initErr)
return initErr return initErr
} }
@@ -318,7 +318,7 @@ func (app *p2pApp) buildRelayTunnel() error {
AppID: app.id, AppID: app.id,
AppKey: app.key, AppKey: app.key,
} }
gLog.Printf(LvDEBUG, "sync appkey relay to %s", config.LogPeerNode()) gLog.Printf(LvDEBUG, "appid:%d buildRelayTunnel sync appkey relay to %s", app.id, config.LogPeerNode())
pn.push(config.PeerNode, MsgPushAPPKey, &syncKeyReq) pn.push(config.PeerNode, MsgPushAPPKey, &syncKeyReq)
app.setRelayTunnelID(rtid) app.setRelayTunnelID(rtid)
app.setRelayTunnel(t) app.setRelayTunnel(t)
@@ -330,9 +330,9 @@ func (app *p2pApp) buildRelayTunnel() error {
if config.SrcPort == 0 { if config.SrcPort == 0 {
req := ServerSideSaveMemApp{From: gConf.Network.Node, Node: relayNode, TunnelID: rtid, RelayTunnelID: t.id, AppID: app.id, RelayMode: relayMode} req := ServerSideSaveMemApp{From: gConf.Network.Node, Node: relayNode, TunnelID: rtid, RelayTunnelID: t.id, AppID: app.id, RelayMode: relayMode}
pn.push(config.PeerNode, MsgPushServerSideSaveMemApp, &req) pn.push(config.PeerNode, MsgPushServerSideSaveMemApp, &req)
gLog.Printf(LvDEBUG, "push %s relay ServerSideSaveMemApp: %s", config.LogPeerNode(), prettyJson(req)) gLog.Printf(LvDEBUG, "appid:%d buildRelayTunnel push %s relay ServerSideSaveMemApp: %s", app.id, config.LogPeerNode(), prettyJson(req))
} }
gLog.Printf(LvDEBUG, "%s use tunnel %d", app.config.AppName, t.id) gLog.Printf(LvDEBUG, "appid:%d buildRelayTunnel %s use tunnel %d", app.id, app.config.AppName, t.id)
return nil return nil
} }
@@ -380,8 +380,8 @@ func (app *p2pApp) updateHeartbeat() {
} }
func (app *p2pApp) listenTCP() error { func (app *p2pApp) listenTCP() error {
gLog.Printf(LvDEBUG, "tcp accept on port %d start", app.config.SrcPort) gLog.Printf(LvDEBUG, "appid:%d tcp accept on port %d start", app.id, app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "tcp accept on port %d end", app.config.SrcPort) defer gLog.Printf(LvDEBUG, "appid:%d tcp accept on port %d end", app.id, app.config.SrcPort)
var err error var err error
listenAddr := "" listenAddr := ""
if IsLocalhost(app.config.Whitelist) { // not expose port if IsLocalhost(app.config.Whitelist) { // not expose port
@@ -389,7 +389,7 @@ func (app *p2pApp) listenTCP() error {
} }
app.listener, err = net.Listen("tcp", fmt.Sprintf("%s:%d", listenAddr, app.config.SrcPort)) app.listener, err = net.Listen("tcp", fmt.Sprintf("%s:%d", listenAddr, app.config.SrcPort))
if err != nil { if err != nil {
gLog.Printf(LvERROR, "listen error:%s", err) gLog.Printf(LvERROR, "appid:%d listen error:%s", app.id, err)
return err return err
} }
defer app.listener.Close() defer app.listener.Close()
@@ -397,12 +397,12 @@ func (app *p2pApp) listenTCP() error {
conn, err := app.listener.Accept() conn, err := app.listener.Accept()
if err != nil { if err != nil {
if app.running { if app.running {
gLog.Printf(LvERROR, "%d accept error:%s", app.id, err) gLog.Printf(LvERROR, "appid:%d accept error:%s", app.id, err)
} }
break break
} }
if app.Tunnel() == nil { if app.Tunnel() == nil {
gLog.Printf(LvDEBUG, "srcPort=%d, app.Tunnel()==nil, not ready", app.config.SrcPort) gLog.Printf(LvDEBUG, "appid:%d srcPort=%d, app.Tunnel()==nil, not ready", app.id, app.config.SrcPort)
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
@@ -411,7 +411,7 @@ func (app *p2pApp) listenTCP() error {
remoteIP := conn.RemoteAddr().(*net.TCPAddr).IP.String() remoteIP := conn.RemoteAddr().(*net.TCPAddr).IP.String()
if !app.iptree.Contains(remoteIP) && !IsLocalhost(remoteIP) { if !app.iptree.Contains(remoteIP) && !IsLocalhost(remoteIP) {
conn.Close() conn.Close()
gLog.Printf(LvERROR, "%s not in whitelist, access denied", remoteIP) gLog.Printf(LvERROR, "appid:%d %s not in whitelist, access denied", app.id, remoteIP)
continue continue
} }
} }
@@ -436,7 +436,7 @@ func (app *p2pApp) listenTCP() error {
oConn.appKeyBytes = encryptKey oConn.appKeyBytes = encryptKey
} }
app.Tunnel().overlayConns.Store(oConn.id, &oConn) app.Tunnel().overlayConns.Store(oConn.id, &oConn)
gLog.Printf(LvDEBUG, "Accept TCP overlayID:%d, %s", oConn.id, oConn.connTCP.RemoteAddr()) gLog.Printf(LvDEBUG, "appid:%d Accept TCP overlayID:%d, %s", app.id, oConn.id, oConn.connTCP.RemoteAddr())
// tell peer connect // tell peer connect
req := OverlayConnectReq{ID: oConn.id, req := OverlayConnectReq{ID: oConn.id,
Token: gConf.Network.Token, Token: gConf.Network.Token,
@@ -457,12 +457,12 @@ func (app *p2pApp) listenTCP() error {
} }
func (app *p2pApp) listenUDP() error { func (app *p2pApp) listenUDP() error {
gLog.Printf(LvDEBUG, "udp accept on port %d start", app.config.SrcPort) gLog.Printf(LvDEBUG, "appid:%d udp accept on port %d start", app.id, app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "udp accept on port %d end", app.config.SrcPort) defer gLog.Printf(LvDEBUG, "appid:%d udp accept on port %d end", app.id, app.config.SrcPort)
var err error var err error
app.listenerUDP, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: app.config.SrcPort}) app.listenerUDP, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: app.config.SrcPort})
if err != nil { if err != nil {
gLog.Printf(LvERROR, "listen error:%s", err) gLog.Printf(LvERROR, "appid:%d listen error:%s", app.id, err)
return err return err
} }
defer app.listenerUDP.Close() defer app.listenerUDP.Close()
@@ -475,12 +475,12 @@ func (app *p2pApp) listenUDP() error {
if ne, ok := err.(net.Error); ok && ne.Timeout() { if ne, ok := err.(net.Error); ok && ne.Timeout() {
continue continue
} else { } else {
gLog.Printf(LvERROR, "udp read failed:%s", err) gLog.Printf(LvERROR, "appid:%d udp read failed:%s", app.id, err)
break break
} }
} else { } else {
if app.Tunnel() == nil { if app.Tunnel() == nil {
gLog.Printf(LvDEBUG, "srcPort=%d, app.Tunnel()==nil, not ready", app.config.SrcPort) gLog.Printf(LvDEBUG, "appid:%d srcPort=%d, app.Tunnel()==nil, not ready", app.id, app.config.SrcPort)
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
@@ -521,7 +521,7 @@ func (app *p2pApp) listenUDP() error {
oConn.appKeyBytes = encryptKey oConn.appKeyBytes = encryptKey
} }
app.Tunnel().overlayConns.Store(oConn.id, &oConn) app.Tunnel().overlayConns.Store(oConn.id, &oConn)
gLog.Printf(LvDEBUG, "Accept UDP overlayID:%d", oConn.id) gLog.Printf(LvDEBUG, "appid:%d Accept UDP overlayID:%d", app.id, oConn.id)
// tell peer connect // tell peer connect
req := OverlayConnectReq{ID: oConn.id, req := OverlayConnectReq{ID: oConn.id,
Token: gConf.Network.Token, Token: gConf.Network.Token,
@@ -555,8 +555,8 @@ func (app *p2pApp) listen() error {
if app.config.SrcPort == 0 { if app.config.SrcPort == 0 {
return nil return nil
} }
gLog.Printf(LvINFO, "LISTEN ON PORT %s:%d START", app.config.Protocol, app.config.SrcPort) gLog.Printf(LvINFO, "appid:%d LISTEN ON PORT %s:%d START", app.id, app.config.Protocol, app.config.SrcPort)
defer gLog.Printf(LvINFO, "LISTEN ON PORT %s:%d END", app.config.Protocol, app.config.SrcPort) defer gLog.Printf(LvINFO, "appid:%d LISTEN ON PORT %s:%d END", app.id, app.config.Protocol, app.config.SrcPort)
app.wg.Add(1) app.wg.Add(1)
defer app.wg.Done() defer app.wg.Done()
for app.running { for app.running {
@@ -594,8 +594,8 @@ func (app *p2pApp) close() {
func (app *p2pApp) relayHeartbeatLoop() { func (app *p2pApp) relayHeartbeatLoop() {
app.wg.Add(1) app.wg.Add(1)
defer app.wg.Done() defer app.wg.Done()
gLog.Printf(LvDEBUG, "%s appid:%d relayHeartbeat to rtid:%d start", app.config.LogPeerNode(), app.id, app.rtid) gLog.Printf(LvDEBUG, "appid:%d %s relayHeartbeat to rtid:%d start", app.id, app.config.LogPeerNode(), app.rtid)
defer gLog.Printf(LvDEBUG, "%s appid:%d relayHeartbeat to rtid%d end", app.config.LogPeerNode(), app.id, app.rtid) defer gLog.Printf(LvDEBUG, "appid:%d %s relayHeartbeat to rtid%d end", app.id, app.config.LogPeerNode(), app.rtid)
for app.running { for app.running {
if app.RelayTunnel() == nil || !app.RelayTunnel().isRuning() { if app.RelayTunnel() == nil || !app.RelayTunnel().isRuning() {
@@ -606,11 +606,11 @@ func (app *p2pApp) relayHeartbeatLoop() {
AppID: app.id} AppID: app.id}
err := app.RelayTunnel().WriteMessage(app.rtid, MsgP2P, MsgRelayHeartbeat, &req) err := app.RelayTunnel().WriteMessage(app.rtid, MsgP2P, MsgRelayHeartbeat, &req)
if err != nil { if err != nil {
gLog.Printf(LvERROR, "%s appid:%d rtid:%d write relay tunnel heartbeat error %s", app.config.LogPeerNode(), app.id, app.rtid, err) gLog.Printf(LvERROR, "appid:%d %s rtid:%d write relay tunnel heartbeat error %s", app.id, app.config.LogPeerNode(), app.rtid, err)
return return
} }
// TODO: debug relay heartbeat // TODO: debug relay heartbeat
gLog.Printf(LvDEBUG, "%s appid:%d rtid:%d write relay tunnel heartbeat ok", app.config.LogPeerNode(), app.id, app.rtid) gLog.Printf(LvDEBUG, "appid:%d %s rtid:%d write relay tunnel heartbeat ok", app.id, app.config.LogPeerNode(), app.rtid)
time.Sleep(TunnelHeartbeatTime) time.Sleep(TunnelHeartbeatTime)
} }
} }
+13 -6
View File
@@ -2,6 +2,7 @@ package openp2p
import ( import (
"bytes" "bytes"
"context"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"encoding/binary" "encoding/binary"
@@ -9,6 +10,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/rand" "math/rand"
"net"
"net/http" "net/http"
"net/url" "net/url"
"reflect" "reflect"
@@ -497,6 +499,12 @@ func (pn *P2PNetwork) init() error {
pn.wgReconnect.Add(1) pn.wgReconnect.Add(1)
defer pn.wgReconnect.Done() defer pn.wgReconnect.Done()
var err error var err error
net.DefaultResolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return net.Dial("udp", "119.29.29.29:53")
},
}
for { for {
// detect nat type // detect nat type
gConf.Network.publicIP, gConf.Network.natType, err = getNATType(gConf.Network.ServerHost, gConf.Network.UDPPort1, gConf.Network.UDPPort2) gConf.Network.publicIP, gConf.Network.natType, err = getNATType(gConf.Network.ServerHost, gConf.Network.UDPPort1, gConf.Network.UDPPort2)
@@ -523,12 +531,11 @@ func (pn *P2PNetwork) init() error {
gLog.Println(LvINFO, "openp2pC2CTest debug") gLog.Println(LvINFO, "openp2pC2CTest debug")
} }
if gConf.Network.hasIPv4 == 1 || gConf.Network.hasUPNPorNATPMP == 1 { // public ip and intranet connect
onceV4Listener.Do(func() { onceV4Listener.Do(func() {
v4l = &v4Listener{port: gConf.Network.TCPPort} v4l = &v4Listener{port: gConf.Network.TCPPort}
go v4l.start() go v4l.start()
}) })
}
gLog.Printf(LvINFO, "hasIPv4:%d, UPNP:%d, NAT type:%d, publicIP:%s", gConf.Network.hasIPv4, gConf.Network.hasUPNPorNATPMP, gConf.Network.natType, gConf.Network.publicIP) gLog.Printf(LvINFO, "hasIPv4:%d, UPNP:%d, NAT type:%d, publicIP:%s", gConf.Network.hasIPv4, gConf.Network.hasUPNPorNATPMP, gConf.Network.natType, gConf.Network.publicIP)
gatewayURL := fmt.Sprintf("%s:%d", gConf.Network.ServerHost, gConf.Network.ServerPort) gatewayURL := fmt.Sprintf("%s:%d", gConf.Network.ServerHost, gConf.Network.ServerPort)
uri := "/api/v1/login" uri := "/api/v1/login"
-1
View File
@@ -5,7 +5,6 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"runtime"
"strings" "strings"
"syscall" "syscall"
) )