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

View File

@@ -174,7 +174,7 @@ func (c *Config) retryApp(peerNode string) {
app.hbMtx.Unlock()
}
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.nextRetryRelayTime = time.Now()
app.hbMtx.Lock()
@@ -423,7 +423,6 @@ func parseParams(subCommand string, cmd string) {
fset.Parse(os.Args[2:])
}
} else {
gLog.Println(LvINFO, "cmd=", cmd)
args := strings.Split(cmd, " ")
fset.Parse(args)
}

View File

@@ -1,7 +1,6 @@
package openp2p
import (
"fmt"
"os"
"path/filepath"
"time"
@@ -15,12 +14,12 @@ type daemon struct {
}
func (d *daemon) Start(s service.Service) error {
gLog.Println(LvINFO, "daemon start")
gLog.Println(LvINFO, "system service start")
return nil
}
func (d *daemon) Stop(s service.Service) error {
gLog.Println(LvINFO, "service stop")
gLog.Println(LvINFO, "system service stop")
d.running = false
if d.proc != nil {
gLog.Println(LvINFO, "stop worker")
@@ -38,11 +37,6 @@ func (d *daemon) run() {
defer gLog.Println(LvINFO, "daemon run end")
d.running = true
binPath, _ := os.Executable()
mydir, err := os.Getwd()
if err != nil {
fmt.Println(err)
}
gLog.Println(LvINFO, mydir)
conf := &service.Config{
Name: ProductName,
DisplayName: ProductName,
@@ -68,7 +62,7 @@ func (d *daemon) run() {
dumpFile := filepath.Join("log", "dump.log")
f, err := os.Create(filepath.Join(tmpDump))
if err != nil {
gLog.Printf(LvERROR, "start worker error:%s", err)
gLog.Printf(LvERROR, "create file %s error:%s", tmpDump, err)
return
}
gLog.Println(LvINFO, "start worker process, args:", args)

View File

@@ -28,7 +28,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushRsp:
rsp := PushRsp{}
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
}
if rsp.Error == 0 {
@@ -39,7 +39,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushAddRelayTunnelReq:
req := AddRelayTunnelReq{}
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
}
config := AppConfig{}
@@ -62,7 +62,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushServerSideSaveMemApp:
req := ServerSideSaveMemApp{}
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
}
gLog.Println(LvDEBUG, "handle MsgPushServerSideSaveMemApp:", prettyJson(req))
@@ -91,7 +91,7 @@ func handlePush(subType uint16, msg []byte) error {
} else {
app.setRelayTunnel(existTunnel)
}
gLog.Println(LvDEBUG, "find existing memapp, update it")
gLog.Println(LvDEBUG, "found existing memapp, update it")
} else {
appConfig := existTunnel.config
appConfig.SrcPort = 0
@@ -121,7 +121,7 @@ func handlePush(subType uint16, msg []byte) error {
case MsgPushAPPKey:
req := APPKeySync{}
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
}
SaveKey(req.AppID, req.AppKey)
@@ -152,7 +152,7 @@ func handlePush(subType uint16, msg []byte) error {
gLog.Println(LvINFO, "MsgPushEditNode")
req := EditNode{}
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
}
gConf.setNode(req.NewName)
@@ -162,7 +162,7 @@ func handlePush(subType uint16, msg []byte) error {
gLog.Println(LvINFO, "MsgPushSwitchApp")
app := AppInfo{}
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
}
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)
}
case MsgPushDstNodeOnline:
gLog.Println(LvINFO, "MsgPushDstNodeOnline")
req := PushDstNodeOnline{}
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
}
gLog.Println(LvINFO, "retry peerNode ", req.Node)
gLog.Printf(LvINFO, "%s online, retryApp", req.Node)
gConf.retryApp(req.Node)
default:
i, ok := GNetwork.msgMap.Load(pushHead.From)
@@ -196,7 +195,7 @@ func handleEditApp(msg []byte) (err error) {
gLog.Println(LvINFO, "MsgPushEditApp")
newApp := AppInfo{}
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
}
oldConf := AppConfig{Enabled: 1}
@@ -228,11 +227,10 @@ func handleEditApp(msg []byte) (err error) {
func handleConnectReq(msg []byte) (err error) {
req := PushConnectReq{}
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
}
gLog.Printf(LvDEBUG, "%s is connecting...", req.From)
gLog.Println(LvDEBUG, "push connect response to ", req.From)
gLog.Printf(LvDEBUG, "%s is connecting... push connect response", req.From)
if compareVersion(req.Version, LeastSupportVersion) < 0 {
gLog.Println(LvERROR, ErrVersionNotCompatible.Error(), ":", req.From)
rsp := PushConnectRsp{
@@ -247,7 +245,7 @@ func handleConnectReq(msg []byte) (err error) {
// verify totp token or token
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
gLog.Printf(LvINFO, "Access Granted")
gLog.Printf(LvINFO, "handleConnectReq Access Granted")
config := AppConfig{}
config.peerNatType = req.NatType
config.peerConeNatPort = req.ConeNatPort
@@ -272,7 +270,7 @@ func handleConnectReq(msg []byte) (err error) {
}()
return nil
}
gLog.Println(LvERROR, "Access Denied:", req.From)
gLog.Println(LvERROR, "handleConnectReq Access Denied:", req.From)
rsp := PushConnectRsp{
Error: 1,
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
req := ReportLogReq{}
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
}
if req.FileName == "" {
@@ -467,7 +465,7 @@ func handleCheckRemoteService(msg []byte) (err error) {
gLog.Println(LvDEBUG, "handleCheckRemoteService")
req := CheckRemoteService{}
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
}
rsp := PushRsp{Error: 0}

View File

@@ -39,19 +39,19 @@ func handshakeC2C(t *P2PTunnel) (err error) {
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})
_, head, _, _, err = UDPRead(conn, HandshakeTimeout)
if err != nil {
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error:", err)
return err
}
}
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})
if err != nil {
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error", err)
gLog.Println(LvDEBUG, "handshakeC2C write MsgPunchHandshakeAck error:", err)
return err
}
}
@@ -60,8 +60,8 @@ func handshakeC2C(t *P2PTunnel) (err error) {
}
func handshakeC2S(t *P2PTunnel) error {
gLog.Printf(LvDEBUG, "handshakeC2S start")
defer gLog.Printf(LvDEBUG, "handshakeC2S end")
gLog.Printf(LvDEBUG, "tid:%d handshakeC2S start", t.id)
defer gLog.Printf(LvDEBUG, "tid:%d handshakeC2S end", t.id)
if !buildTunnelMtx.TryLock() {
// time.Sleep(time.Second * 3)
return ErrBuildTunnelBusy
@@ -77,7 +77,7 @@ func handshakeC2S(t *P2PTunnel) error {
defer conn.Close()
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++ {
// time.Sleep(SymmetricHandshakeInterval)
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})
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
}
}
gLog.Println(LvDEBUG, "send symmetric handshake end")
gLog.Printf(LvDEBUG, "tid:%d send symmetric handshake end", t.id)
return nil
}()
err = conn.SetReadDeadline(time.Now().Add(HandshakeTimeout))
if err != nil {
gLog.Println(LvERROR, "SymmetricHandshakeAckTimeout SetReadDeadline error")
gLog.Println(LvERROR, "tid:%d SymmetricHandshakeAckTimeout SetReadDeadline error", t.id)
return err
}
// read response of the punching hole ok port
buff := make([]byte, 1024)
_, dst, err := conn.ReadFrom(buff)
if err != nil {
gLog.Println(LvERROR, "handshakeC2S wait timeout")
gLog.Println(LvERROR, "tid:%d handshakeC2S wait timeout", t.id)
return err
}
head := &openP2PHeader{}
err = binary.Read(bytes.NewReader(buff[:openP2PHeaderSize]), binary.LittleEndian, head)
if err != nil {
gLog.Println(LvERROR, "parse p2pheader error:", err)
gLog.Printf(LvERROR, "tid:%d parse p2pheader error:%s", t.id, err)
return err
}
t.remoteHoleAddr, _ = net.ResolveUDPAddr("udp", dst.String())
@@ -122,12 +122,12 @@ func handshakeC2S(t *P2PTunnel) error {
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})
for {
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
if err != nil {
gLog.Println(LvDEBUG, "handshakeC2S handshake error")
gLog.Printf(LvDEBUG, "tid:%d handshakeC2S handshake error", t.id)
return err
}
var tunnelID uint64
@@ -146,19 +146,19 @@ func handshakeC2S(t *P2PTunnel) error {
}
}
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})
return err
} 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
}
func handshakeS2C(t *P2PTunnel) error {
gLog.Printf(LvDEBUG, "handshakeS2C start")
defer gLog.Printf(LvDEBUG, "handshakeS2C end")
gLog.Printf(LvDEBUG, "tid:%d handshakeS2C start", t.id)
defer gLog.Printf(LvDEBUG, "tid:%d handshakeS2C end", t.id)
if !buildTunnelMtx.TryLock() {
// time.Sleep(time.Second * 3)
return ErrBuildTunnelBusy
@@ -167,14 +167,14 @@ func handshakeS2C(t *P2PTunnel) error {
startTime := time.Now()
gotCh := make(chan *net.UDPAddr, 5)
// 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
for i := 0; i < SymmetricHandshakeNum; i++ {
// time.Sleep(SymmetricHandshakeInterval)
go func(t *P2PTunnel) error {
conn, err := net.ListenUDP("udp", nil) // TODO: system allocated port really random?
if err != nil {
gLog.Printf(LvDEBUG, "listen error")
gLog.Printf(LvDEBUG, "tid:%d listen error", t.id)
return err
}
defer conn.Close()
@@ -198,13 +198,13 @@ func handshakeS2C(t *P2PTunnel) error {
}
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})
// may read several MsgPunchHandshake
for {
_, head, buff, _, err = UDPRead(conn, HandshakeTimeout)
if err != nil {
gLog.Println(LvDEBUG, "handshakeS2C handshake error")
gLog.Println(LvDEBUG, "tid:%d handshakeS2C handshake error", t.id)
return err
}
if len(buff) > openP2PHeaderSize {
@@ -218,36 +218,35 @@ func handshakeS2C(t *P2PTunnel) error {
if head.MainType == MsgP2P && head.SubType == MsgPunchHandshakeAck && tunnelID == t.id {
break
} 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 {
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})
gotIt = true
la, _ := net.ResolveUDPAddr("udp", conn.LocalAddr().String())
gotCh <- la
return nil
} 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
}(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
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})
}
select {
case <-time.After(HandshakeTimeout):
return fmt.Errorf("wait handshake timeout")
return fmt.Errorf("tid:%d wait handshake timeout", t.id)
case la := <-gotCh:
t.localHoleAddr = la
gLog.Println(LvDEBUG, "symmetric handshake ok", la)
gLog.Printf(LvINFO, "handshakeS2C ok. cost %dms", time.Since(startTime)/time.Millisecond)
gLog.Printf(LvINFO, "tid:%d handshakeS2C ok. cost %dms", t.id, time.Since(startTime)/time.Millisecond)
}
return nil
}

View File

@@ -24,7 +24,7 @@ func install() {
}
err = os.Chdir(defaultInstallPath)
if err != nil {
gLog.Println(LvERROR, "cd error:", err)
gLog.Println(LvERROR, "Chdir error:", err)
return
}
@@ -38,7 +38,7 @@ func install() {
binPath, _ := os.Executable()
src, errFiles := os.Open(binPath) // can not use args[0], on Windows call openp2p is ok(=openp2p.exe)
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
}
@@ -57,7 +57,6 @@ func install() {
dst.Close()
// install system service
gLog.Println(LvINFO, "targetPath:", targetPath)
err = d.Control("install", targetPath, []string{"-d"})
if err == nil {
gLog.Println(LvINFO, "install system service ok.")

View File

@@ -41,7 +41,7 @@ func Run() {
return
}
gLog.Println(LvINFO, &gConf)
gLog.Printf(LvINFO, "node=%s, serverHost=%s, serverPort=%d", gConf.Network.Node, gConf.Network.ServerHost, gConf.Network.ServerPort)
setFirewall()
err := setRLimit()
if err != nil {
@@ -78,7 +78,7 @@ func RunAsModule(baseDir string, token string, bw int, logLevel int) *P2PNetwork
gConf.setShareBandwidth(bw)
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
gLog.Println(LvINFO, "Contact: QQ group 16947733, Email openp2p.cn@gmail.com")
gLog.Println(LvINFO, &gConf)
gLog.Printf(LvINFO, "node=%s, serverHost=%s, serverPort=%d", gConf.Network.Node, gConf.Network.ServerHost, gConf.Network.ServerPort)
GNetwork = P2PNetworkInstance()
if ok := GNetwork.Connect(30000); !ok {

View File

@@ -3,40 +3,131 @@
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 (
tunIfaceName = "optun"
PIHeaderSize = 0
)
var previousIP = ""
func (t *optun) Start(localAddr string, detail *SDWANInfo) error {
var err error
t.tunName = tunIfaceName
t.dev, err = tun.CreateTUN(t.tunName, 1420)
if err != nil {
return err
}
err = setTunAddr(t.tunName, localAddr, detail.Gateway, t.dev)
if err != nil {
return err
}
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 {
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 {
return nil
}
func addTunAddr(localAddr, remoteAddr string) error {
return nil
_, networkid, err := net.ParseCIDR(dst)
if err != nil {
return err
}
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
}

View File

@@ -41,8 +41,8 @@ type overlayConn struct {
}
func (oConn *overlayConn) run() {
gLog.Printf(LvDEBUG, "%d overlayConn run start", oConn.id)
defer gLog.Printf(LvDEBUG, "%d overlayConn run end", oConn.id)
gLog.Printf(LvDEBUG, "oid:%d overlayConn run start", oConn.id)
defer gLog.Printf(LvDEBUG, "oid:%d overlayConn run end", oConn.id)
oConn.lastReadUDPTs = time.Now()
buffer := make([]byte, ReadBuffLen+PaddingSize) // 16 bytes for padding
reuseBuff := buffer[:ReadBuffLen]
@@ -58,7 +58,7 @@ func (oConn *overlayConn) run() {
continue
}
// 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
}
payload := readBuff[:dataLen]
@@ -69,13 +69,13 @@ func (oConn *overlayConn) run() {
// TODO: app.write
if oConn.rtid == 0 {
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 {
// write raley data
all := append(relayHead.Bytes(), encodeHeader(MsgP2P, MsgOverlayData, uint32(len(writeBytes)))...)
all = append(all, writeBytes...)
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 {

View File

@@ -138,7 +138,7 @@ func (app *p2pApp) checkDirectTunnel() error {
app.config.retryNum = 1
}
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.retryTime = time.Now()
@@ -149,7 +149,7 @@ func (app *p2pApp) checkDirectTunnel() error {
app.config.errMsg = err.Error()
if err == ErrPeerOffline && app.config.retryNum > 2 { // stop retry, waiting for online
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 {
app.config.retryNum--
@@ -174,7 +174,7 @@ func (app *p2pApp) buildDirectTunnel() error {
pn := GNetwork
initErr := pn.requestPeerInfo(&app.config)
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
}
t, err = pn.addDirectTunnel(app.config, 0)
@@ -212,7 +212,7 @@ func (app *p2pApp) buildDirectTunnel() error {
AppID: app.id,
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)
app.setDirectTunnel(t)
@@ -220,9 +220,9 @@ func (app *p2pApp) buildDirectTunnel() error {
if app.config.SrcPort == 0 {
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)
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
}
@@ -244,7 +244,7 @@ func (app *p2pApp) checkRelayTunnel() error {
app.retryRelayNum = 1
}
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.retryRelayNum++
@@ -256,7 +256,7 @@ func (app *p2pApp) checkRelayTunnel() error {
app.errMsg = err.Error()
if err == ErrPeerOffline && app.retryRelayNum > 2 { // stop retry, waiting for online
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 {
@@ -282,7 +282,7 @@ func (app *p2pApp) buildRelayTunnel() error {
config := app.config
initErr := pn.requestPeerInfo(&config)
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
}
@@ -318,7 +318,7 @@ func (app *p2pApp) buildRelayTunnel() error {
AppID: app.id,
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)
app.setRelayTunnelID(rtid)
app.setRelayTunnel(t)
@@ -330,9 +330,9 @@ func (app *p2pApp) buildRelayTunnel() error {
if config.SrcPort == 0 {
req := ServerSideSaveMemApp{From: gConf.Network.Node, Node: relayNode, TunnelID: rtid, RelayTunnelID: t.id, AppID: app.id, RelayMode: relayMode}
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
}
@@ -380,8 +380,8 @@ func (app *p2pApp) updateHeartbeat() {
}
func (app *p2pApp) listenTCP() error {
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)
gLog.Printf(LvDEBUG, "appid:%d tcp accept on port %d start", app.id, app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "appid:%d tcp accept on port %d end", app.id, app.config.SrcPort)
var err error
listenAddr := ""
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))
if err != nil {
gLog.Printf(LvERROR, "listen error:%s", err)
gLog.Printf(LvERROR, "appid:%d listen error:%s", app.id, err)
return err
}
defer app.listener.Close()
@@ -397,12 +397,12 @@ func (app *p2pApp) listenTCP() error {
conn, err := app.listener.Accept()
if err != nil {
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
}
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)
continue
}
@@ -411,7 +411,7 @@ func (app *p2pApp) listenTCP() error {
remoteIP := conn.RemoteAddr().(*net.TCPAddr).IP.String()
if !app.iptree.Contains(remoteIP) && !IsLocalhost(remoteIP) {
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
}
}
@@ -436,7 +436,7 @@ func (app *p2pApp) listenTCP() error {
oConn.appKeyBytes = encryptKey
}
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
req := OverlayConnectReq{ID: oConn.id,
Token: gConf.Network.Token,
@@ -457,12 +457,12 @@ func (app *p2pApp) listenTCP() error {
}
func (app *p2pApp) listenUDP() error {
gLog.Printf(LvDEBUG, "udp accept on port %d start", app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "udp accept on port %d end", app.config.SrcPort)
gLog.Printf(LvDEBUG, "appid:%d udp accept on port %d start", app.id, app.config.SrcPort)
defer gLog.Printf(LvDEBUG, "appid:%d udp accept on port %d end", app.id, app.config.SrcPort)
var err error
app.listenerUDP, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: app.config.SrcPort})
if err != nil {
gLog.Printf(LvERROR, "listen error:%s", err)
gLog.Printf(LvERROR, "appid:%d listen error:%s", app.id, err)
return err
}
defer app.listenerUDP.Close()
@@ -475,12 +475,12 @@ func (app *p2pApp) listenUDP() error {
if ne, ok := err.(net.Error); ok && ne.Timeout() {
continue
} else {
gLog.Printf(LvERROR, "udp read failed:%s", err)
gLog.Printf(LvERROR, "appid:%d udp read failed:%s", app.id, err)
break
}
} else {
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)
continue
}
@@ -521,7 +521,7 @@ func (app *p2pApp) listenUDP() error {
oConn.appKeyBytes = encryptKey
}
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
req := OverlayConnectReq{ID: oConn.id,
Token: gConf.Network.Token,
@@ -555,8 +555,8 @@ func (app *p2pApp) listen() error {
if app.config.SrcPort == 0 {
return nil
}
gLog.Printf(LvINFO, "LISTEN ON PORT %s:%d START", app.config.Protocol, app.config.SrcPort)
defer gLog.Printf(LvINFO, "LISTEN ON PORT %s:%d END", 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, "appid:%d LISTEN ON PORT %s:%d END", app.id, app.config.Protocol, app.config.SrcPort)
app.wg.Add(1)
defer app.wg.Done()
for app.running {
@@ -594,8 +594,8 @@ func (app *p2pApp) close() {
func (app *p2pApp) relayHeartbeatLoop() {
app.wg.Add(1)
defer app.wg.Done()
gLog.Printf(LvDEBUG, "%s appid:%d relayHeartbeat to rtid:%d start", app.config.LogPeerNode(), app.id, app.rtid)
defer gLog.Printf(LvDEBUG, "%s appid:%d relayHeartbeat to rtid%d end", 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, "appid:%d %s relayHeartbeat to rtid%d end", app.id, app.config.LogPeerNode(), app.rtid)
for app.running {
if app.RelayTunnel() == nil || !app.RelayTunnel().isRuning() {
@@ -606,11 +606,11 @@ func (app *p2pApp) relayHeartbeatLoop() {
AppID: app.id}
err := app.RelayTunnel().WriteMessage(app.rtid, MsgP2P, MsgRelayHeartbeat, &req)
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
}
// 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)
}
}

View File

@@ -2,6 +2,7 @@ package openp2p
import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"encoding/binary"
@@ -9,6 +10,7 @@ import (
"errors"
"fmt"
"math/rand"
"net"
"net/http"
"net/url"
"reflect"
@@ -497,6 +499,12 @@ func (pn *P2PNetwork) init() error {
pn.wgReconnect.Add(1)
defer pn.wgReconnect.Done()
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 {
// detect nat type
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")
}
if gConf.Network.hasIPv4 == 1 || gConf.Network.hasUPNPorNATPMP == 1 {
onceV4Listener.Do(func() {
v4l = &v4Listener{port: gConf.Network.TCPPort}
go v4l.start()
})
}
// public ip and intranet connect
onceV4Listener.Do(func() {
v4l = &v4Listener{port: gConf.Network.TCPPort}
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)
gatewayURL := fmt.Sprintf("%s:%d", gConf.Network.ServerHost, gConf.Network.ServerPort)
uri := "/api/v1/login"

View File

@@ -5,7 +5,6 @@ import (
"bytes"
"io/ioutil"
"os"
"runtime"
"strings"
"syscall"
)