diff --git a/core/config.go b/core/config.go index 15ad725..78097a1 100644 --- a/core/config.go +++ b/core/config.go @@ -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) } diff --git a/core/daemon.go b/core/daemon.go index 4e7bbec..306d58a 100644 --- a/core/daemon.go +++ b/core/daemon.go @@ -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) diff --git a/core/handlepush.go b/core/handlepush.go index 8859dcd..52df4ca 100644 --- a/core/handlepush.go +++ b/core/handlepush.go @@ -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} diff --git a/core/holepunch.go b/core/holepunch.go index 2024847..59ac770 100644 --- a/core/holepunch.go +++ b/core/holepunch.go @@ -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 } diff --git a/core/install.go b/core/install.go index 5a3f035..b2af6b9 100644 --- a/core/install.go +++ b/core/install.go @@ -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.") diff --git a/core/openp2p.go b/core/openp2p.go index b83ebb6..2f2f938 100644 --- a/core/openp2p.go +++ b/core/openp2p.go @@ -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 { diff --git a/core/optun_other.go b/core/optun_other.go index c13bea1..d5fecd1 100644 --- a/core/optun_other.go +++ b/core/optun_other.go @@ -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 } diff --git a/core/overlay.go b/core/overlay.go index 39c6699..65b7495 100644 --- a/core/overlay.go +++ b/core/overlay.go @@ -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 { diff --git a/core/p2papp.go b/core/p2papp.go index 40d9736..91b944c 100644 --- a/core/p2papp.go +++ b/core/p2papp.go @@ -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) } } diff --git a/core/p2pnetwork.go b/core/p2pnetwork.go index 7816ec2..0f28ec7 100644 --- a/core/p2pnetwork.go +++ b/core/p2pnetwork.go @@ -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" diff --git a/core/util_freebsd.go b/core/util_freebsd.go index 6e1c50b..b9d4ff3 100644 --- a/core/util_freebsd.go +++ b/core/util_freebsd.go @@ -5,7 +5,6 @@ import ( "bytes" "io/ioutil" "os" - "runtime" "strings" "syscall" )