From 532d3667ce7fc782f3dc7c2752d5ca4d8597efc8 Mon Sep 17 00:00:00 2001 From: TenderIronh Date: Sun, 15 May 2022 13:08:56 +0800 Subject: [PATCH] support ipv6 --- README-ZH.md | 4 +-- README.md | 4 +-- USAGE-ZH.md | 2 +- USAGE.md | 2 +- config.go | 12 ++++++- handlepush.go | 10 ++++-- nat.go | 22 +++++------- p2pnetwork.go | 38 +++++++++++++++++++-- p2ptunnel.go | 88 +++++++++++++++++++++++------------------------- protocol.go | 16 ++++++--- totp.go | 3 ++ underlay_tcp6.go | 6 ++-- update.go | 2 +- 13 files changed, 131 insertions(+), 78 deletions(-) diff --git a/README-ZH.md b/README-ZH.md index 7e9ad28..691a238 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -23,7 +23,7 @@ ### 5. 跨平台 因为轻量,所以很容易支持各个平台。支持主流的操作系统:Windows,Linux,MacOS;和主流的cpu架构:386、amd64、arm、arm64、mipsle、mipsle64、mips、mips64 ### 6. 高效 -P2P直连可以让你的设备跑满带宽。不论你的设备在任何网络环境,无论NAT1-4(Cone或Symmetric),都支持。依靠Quic协议优秀的拥塞算法,能在糟糕的网络环境获得高带宽低延时。 +P2P直连可以让你的设备跑满带宽。不论你的设备在任何网络环境,无论NAT1-4(Cone或Symmetric),UPNP,IPv6都支持。依靠Quic协议优秀的拥塞算法,能在糟糕的网络环境获得高带宽低延时。 ### 7. 二次开发 基于OpenP2P只需数行代码,就能让原来只能局域网通信的程序,变成任何内网都能通信 @@ -105,7 +105,7 @@ go build ## TODO 近期计划: -1. 支持IPv6 +1. 支持IPv6(100%) 2. 支持随系统自动启动,安装成系统服务(100%) 3. 提供一些免费服务器给特别差的网络,如广电网络(100%) 4. 建立网站,用户可以在网站管理所有P2PApp和设备。查看设备在线状态,升级,增删查改重启P2PApp等(100%) diff --git a/README.md b/README.md index 4119680..0659d9f 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The code is open source, the P2P tunnel uses TLS1.3+AES double encryption, and t Benefit from lightweight, it easily supports most of major OS, like Windows, Linux, MacOS, also most of CPU architecture, like 386、amd64、arm、arm64、mipsle、mipsle64、mips、mips64. ### 6. Efficient -P2P direct connection lets your devices make good use of bandwidth. Your device can be connected in any network environments, even supports NAT1-4 (Cone or Symmetric). Relying on the excellent congestion algorithm of the Quic protocol, high bandwidth and low latency can be obtained in a bad network environment. +P2P direct connection lets your devices make good use of bandwidth. Your device can be connected in any network environments, even supports NAT1-4 (Cone or Symmetric),UPNP,IPv6. Relying on the excellent congestion algorithm of the Quic protocol, high bandwidth and low latency can be obtained in a bad network environment. ### 7. Integration Your applicaiton can call OpenP2P with a few code to make any internal networks communicate with each other. @@ -113,7 +113,7 @@ go build ## TODO Short-Term: -1. Support IPv6. +1. Support IPv6.(100%) 2. Support auto run when system boot, setup system service.(100%) 3. Provide free servers to some low-performance network.(100%) 4. Build website, users can manage all P2PApp and devices via it. View devices' online status, upgrade, restart or CURD P2PApp .(100%) diff --git a/USAGE-ZH.md b/USAGE-ZH.md index 8d67b7a..dd0b453 100644 --- a/USAGE-ZH.md +++ b/USAGE-ZH.md @@ -77,7 +77,7 @@ nohup ./openp2p -d -node OFFICEPC1 -token TOKEN & # update local client ./openp2p update # update remote client -curl --insecure 'https://openp2p.cn:27182/api/v1/device/YOUR-NODE-NAME/update?user=&password=' +curl --insecure 'https://api.openp2p.cn:27183/api/v1/device/YOUR-NODE-NAME/update?user=&password=' ``` Windows系统需要设置防火墙放行本程序,程序会自动设置,如果设置失败会影响连接功能。 diff --git a/USAGE.md b/USAGE.md index f73b0cb..89a6994 100644 --- a/USAGE.md +++ b/USAGE.md @@ -79,7 +79,7 @@ Configuration example # update local client ./openp2p update # update remote client -curl --insecure 'https://openp2p.cn:27182/api/v1/device/YOUR-NODE-NAME/update?user=&password=' +curl --insecure 'https://api.openp2p.cn:27183/api/v1/device/YOUR-NODE-NAME/update?user=&password=' ``` Windows system needs to set up firewall for this program, the program will automatically set the firewall, if the setting fails, the UDP punching will be affected. diff --git a/config.go b/config.go index 8e2a7f7..ffb7173 100644 --- a/config.go +++ b/config.go @@ -38,6 +38,7 @@ type AppConfig struct { shareBandwidth int errMsg string connectTime time.Time + fromToken uint64 } // TODO: add loglevel, maxlogfilesize @@ -148,7 +149,6 @@ type NetworkConfig struct { Node string User string localIP string - ipv6 string mac string os string publicIP string @@ -253,3 +253,13 @@ func parseParams(subCommand string) { // gConf.mtx.Unlock() gConf.save() } + +func (conf *AppConfig) isSupportTCP(pnConf NetworkConfig) bool { + if conf.peerVersion == "" || compareVersion(conf.peerVersion, LeastSupportTCPVersion) == LESS { + return false + } + if pnConf.hasIPv4 == 1 || pnConf.hasUPNPorNATPMP == 1 || conf.hasIPv4 == 1 || conf.hasUPNPorNATPMP == 1 || (IsIPv6(pnConf.IPv6) && IsIPv6(conf.IPv6)) { + return true + } + return false +} diff --git a/handlepush.go b/handlepush.go index ec45976..2becf98 100644 --- a/handlepush.go +++ b/handlepush.go @@ -30,8 +30,7 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { gLog.Println(LvDEBUG, "push connect response to ", req.From) // verify totp token or token if VerifyTOTP(req.Token, pn.config.Token, time.Now().Unix()+(pn.serverTs-pn.localTs)) || // localTs may behind, auto adjust ts - VerifyTOTP(req.Token, pn.config.Token, time.Now().Unix()) || - (req.FromToken == pn.config.Token) { + VerifyTOTP(req.Token, pn.config.Token, time.Now().Unix()) { gLog.Printf(LvINFO, "Access Granted\n") config := AppConfig{} config.peerNatType = req.NatType @@ -39,8 +38,10 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { config.peerIP = req.FromIP config.PeerNode = req.From config.peerVersion = req.Version + config.fromToken = req.Token + config.IPv6 = req.IPv6 // share relay node will limit bandwidth - if req.FromToken != pn.config.Token { + if req.Token != pn.config.Token { gLog.Printf(LvINFO, "set share bandwidth %d mbps", pn.config.ShareBandwidth) config.shareBandwidth = pn.config.ShareBandwidth } @@ -124,6 +125,7 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { appActive := 0 relayNode := "" relayMode := "" + linkMode := LinkModeUDPPunch i, ok := pn.apps.Load(fmt.Sprintf("%s%d", config.Protocol, config.SrcPort)) if ok { app := i.(*p2pApp) @@ -132,6 +134,7 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { } relayNode = app.relayNode relayMode = app.relayMode + linkMode = app.tunnel.linkMode } appInfo := AppInfo{ AppName: config.AppName, @@ -140,6 +143,7 @@ func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error { SrcPort: config.SrcPort, RelayNode: relayNode, RelayMode: relayMode, + LinkMode: linkMode, PeerNode: config.PeerNode, DstHost: config.DstHost, DstPort: config.DstPort, diff --git a/nat.go b/nat.go index 092769e..bf5aa30 100644 --- a/nat.go +++ b/nat.go @@ -96,33 +96,29 @@ func natTest(serverHost string, serverPort int, localPort int, echoPort int) (pu return natRsp.IP, hasPublicIP, hasUPNPorNATPMP, natRsp.Port, nil } -func getNATType(host string, udp1 int, udp2 int) (publicIP string, NATType int, hasUPNPorNATPMP int, err error) { +func getNATType(host string, udp1 int, udp2 int) (publicIP string, NATType int, hasIPvr int, hasUPNPorNATPMP int, err error) { // the random local port may be used by other. localPort := int(rand.Uint32()%10000 + 50000) echoPort := int(rand.Uint32()%10000 + 50000) go echo(echoPort) - ip1, hasPublicIP, hasUPNPorNATPMP, port1, err := natTest(host, udp1, localPort, echoPort) + ip1, hasIPv4, hasUPNPorNATPMP, port1, err := natTest(host, udp1, localPort, echoPort) gLog.Printf(LvDEBUG, "local port:%d nat port:%d", localPort, port1) if err != nil { - return "", 0, hasUPNPorNATPMP, err + return "", 0, hasIPv4, hasUPNPorNATPMP, err } - if hasPublicIP == 1 || hasUPNPorNATPMP == 1 { - return ip1, NATNone, hasUPNPorNATPMP, nil - } - ip2, _, _, port2, err := natTest(host, udp2, localPort, 0) // 2rd nat test not need testing publicip + // if hasPublicIP == 1 || hasUPNPorNATPMP == 1 { + // return ip1, NATNone, hasUPNPorNATPMP, nil + // } + _, _, _, port2, err := natTest(host, udp2, localPort, 0) // 2rd nat test not need testing publicip gLog.Printf(LvDEBUG, "local port:%d nat port:%d", localPort, port2) if err != nil { - return "", 0, hasUPNPorNATPMP, err - } - if ip1 != ip2 { - return "", 0, hasUPNPorNATPMP, fmt.Errorf("ip have changed, please retry again") + return "", 0, hasIPv4, hasUPNPorNATPMP, err } natType := NATSymmetric if port1 == port2 { natType = NATCone } - //TODO: NATNone - return ip1, natType, hasUPNPorNATPMP, nil + return ip1, natType, hasIPv4, hasUPNPorNATPMP, nil } func echo(echoPort int) { diff --git a/p2pnetwork.go b/p2pnetwork.go index 9f3934d..2871862 100644 --- a/p2pnetwork.go +++ b/p2pnetwork.go @@ -9,6 +9,7 @@ import ( "fmt" "math" "math/rand" + "net/http" "net/url" "strings" "sync" @@ -236,6 +237,14 @@ func (pn *P2PNetwork) AddApp(config AppConfig) error { peerNatType = t.config.peerNatType peerIP = t.config.peerIP } + // TODO: if tcp failed, should try udp punching, nattype should refactor also, when NATNONE and failed we don't know the peerNatType + // if err != nil && err == ErrorHandshake && t.isSupportTCP() { + // t, err = pn.addDirectTunnel(config, 0) + // if t != nil { + // peerNatType = t.config.peerNatType + // peerIP = t.config.peerIP + // } + // } if err != nil && err == ErrorHandshake { gLog.Println(LvERROR, "direct connect failed, try to relay") t, rtid, relayMode, err = pn.addRelayTunnel(config) @@ -373,13 +382,18 @@ func (pn *P2PNetwork) init() error { var err error for { // detect nat type - pn.config.publicIP, pn.config.natType, pn.config.hasUPNPorNATPMP, err = getNATType(pn.config.ServerHost, pn.config.UDPPort1, pn.config.UDPPort2) + pn.config.publicIP, pn.config.natType, pn.config.hasIPv4, pn.config.hasUPNPorNATPMP, err = getNATType(pn.config.ServerHost, pn.config.UDPPort1, pn.config.UDPPort2) // for testcase if strings.Contains(pn.config.Node, "openp2pS2STest") { pn.config.natType = NATSymmetric + pn.config.hasIPv4 = 0 + pn.config.hasUPNPorNATPMP = 0 + } if strings.Contains(pn.config.Node, "openp2pC2CTest") { pn.config.natType = NATCone + pn.config.hasIPv4 = 0 + pn.config.hasUPNPorNATPMP = 0 } if err != nil { gLog.Println(LvDEBUG, "detect NAT type error:", err) @@ -429,7 +443,7 @@ func (pn *P2PNetwork) init() error { gLog.Println(LvDEBUG, "netinfo:", rsp) if rsp != nil && rsp.Country != "" { if IsIPv6(rsp.IP.String()) { - pn.config.ipv6 = rsp.IP.String() + pn.config.IPv6 = rsp.IP.String() req.IPv6 = rsp.IP.String() } req.NetInfo = *rsp @@ -611,3 +625,23 @@ func (pn *P2PNetwork) updateAppHeartbeat(appID uint64) { return false }) } + +func (pn *P2PNetwork) refreshIPv6() { + if !IsIPv6(pn.config.IPv6) { // not support ipv6, not refresh + return + } + client := &http.Client{Timeout: time.Second * 10} + r, err := client.Get("http://6.ipw.cn") + if err != nil { + gLog.Println(LvINFO, "refreshIPv6 error:", err) + return + } + defer r.Body.Close() + buf := make([]byte, 1024) + n, err := r.Body.Read(buf) + if n <= 0 { + gLog.Println(LvINFO, "netInfo error:", err, n) + return + } + pn.config.IPv6 = string(buf[:n]) +} diff --git a/p2ptunnel.go b/p2ptunnel.go index e6bce01..0310e6e 100644 --- a/p2ptunnel.go +++ b/p2ptunnel.go @@ -28,6 +28,7 @@ type P2PTunnel struct { tunnelServer bool // different from underlayServer coneLocalPort int coneNatPort int + linkMode string } func (t *P2PTunnel) init() { @@ -65,11 +66,11 @@ func (t *P2PTunnel) init() { func (t *P2PTunnel) connect() error { gLog.Printf(LvDEBUG, "start p2pTunnel to %s ", t.config.PeerNode) t.tunnelServer = false + t.pn.refreshIPv6() appKey := uint64(0) req := PushConnectReq{ Token: t.config.peerToken, From: t.pn.config.Node, - FromToken: t.pn.config.Token, FromIP: t.pn.config.publicIP, ConeNatPort: t.coneNatPort, NatType: t.pn.config.natType, @@ -80,6 +81,9 @@ func (t *P2PTunnel) connect() error { AppKey: appKey, Version: OpenP2PVersion, } + if req.Token == 0 { // no relay token + req.Token = t.pn.config.Token + } t.pn.push(t.config.PeerNode, MsgPushConnectReq, req) head, body := t.pn.read(t.config.PeerNode, MsgPush, MsgPushConnectRsp, time.Second*10) if head == nil { @@ -158,7 +162,7 @@ func (t *P2PTunnel) close() { } func (t *P2PTunnel) start() error { - if !t.isSupportTCP() { + if !t.config.isSupportTCP(t.pn.config) { if err := t.handshake(); err != nil { return err } @@ -182,7 +186,7 @@ func (t *P2PTunnel) handshake() error { gLog.Println(LvDEBUG, "handshake to ", t.config.PeerNode) var err error // TODO: handle NATNone, nodes with public ip has no punching - if (t.pn.config.natType == NATCone && t.config.peerNatType == NATCone) || (t.pn.config.natType == NATNone || t.config.peerNatType == NATNone) { + if t.pn.config.natType == NATCone && t.config.peerNatType == NATCone { err = handshakeC2C(t) } else if t.config.peerNatType == NATSymmetric && t.pn.config.natType == NATSymmetric { err = ErrorS2S @@ -203,28 +207,23 @@ func (t *P2PTunnel) handshake() error { } func (t *P2PTunnel) connectUnderlay() (err error) { - if !t.isSupportTCP() { + if !t.config.isSupportTCP(t.pn.config) { t.conn, err = t.connectUnderlayQuic() if err != nil { return err } } else { - // TODO: udp or tcp first? - // prepare a la ra for udp - // t.conn, err = t.connectUnderlayQuic() - // TODO: support ipv6 - // if t.pn.config.hasIPv4 == 1 || t.config.hasIPv4 == 1 { - t.conn, err = t.connectUnderlayTCP() - if err != nil { - return err + if IsIPv6(t.pn.config.IPv6) && IsIPv6(t.config.IPv6) { // both have ipv6 + t.conn, err = t.connectUnderlayTCP6() + if err != nil { + return err + } + } else { // hasipv4 or upnp + t.conn, err = t.connectUnderlayTCP() + if err != nil { + return err + } } - // } - // if IsIPv6(t.pn.config.IPv6) && IsIPv6(t.config.IPv6) { // both have ipv6 - // t.conn, err = t.connectUnderlayTCP6() - // if err != nil { - // return err - // } - // } } t.setRun(true) go t.readLoop() @@ -289,6 +288,7 @@ func (t *P2PTunnel) connectUnderlayQuic() (c underlay, err error) { gLog.Println(LvINFO, "rtt=", time.Since(handshakeBegin)) gLog.Println(LvDEBUG, "quic connection ok") + t.linkMode = LinkModeUDPPunch return qConn, nil } @@ -336,18 +336,19 @@ func (t *P2PTunnel) connectUnderlayTCP() (c underlay, err error) { gLog.Println(LvINFO, "rtt=", time.Since(handshakeBegin)) gLog.Println(LvDEBUG, "TCP connection ok") + t.linkMode = LinkModeIPv4 return qConn, nil } func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) { - gLog.Println(LvINFO, "connectUnderlayTCP start") - defer gLog.Println(LvINFO, "connectUnderlayTCP end") + gLog.Println(LvINFO, "connectUnderlayTCP6 start") + defer gLog.Println(LvINFO, "connectUnderlayTCP6 end") var qConn *underlayTCP6 if t.isUnderlayServer() { t.pn.push(t.config.PeerNode, MsgPushUnderlayConnect, nil) qConn, err = listenTCP6(t.coneNatPort, TunnelIdleTimeout) if err != nil { - return nil, fmt.Errorf("listen TCP error:%s", err) + return nil, fmt.Errorf("listen TCP6 error:%s", err) } _, buff, err := qConn.ReadBuffer() if err != nil { @@ -358,16 +359,16 @@ func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) { gLog.Println(LvDEBUG, string(buff)) } qConn.WriteBytes(MsgP2P, MsgTunnelHandshakeAck, []byte("OpenP2P,hello2")) - gLog.Println(LvDEBUG, "TCP connection ok") + gLog.Println(LvDEBUG, "TCP6 connection ok") return qConn, nil } //else t.pn.read(t.config.PeerNode, MsgPush, MsgPushUnderlayConnect, time.Second*5) - gLog.Println(LvDEBUG, "TCP dial to ", t.ra.String()) + gLog.Println(LvDEBUG, "TCP6 dial to ", t.config.IPv6) qConn, err = dialTCP6(t.config.IPv6, t.config.peerConeNatPort) if err != nil { - return nil, fmt.Errorf("TCP dial to %s error:%s", t.ra.String(), err) + return nil, fmt.Errorf("TCP6 dial to %s:%d error:%s", t.config.IPv6, t.config.peerConeNatPort, err) } handshakeBegin := time.Now() qConn.WriteBytes(MsgP2P, MsgTunnelHandshake, []byte("OpenP2P,hello")) @@ -381,7 +382,8 @@ func (t *P2PTunnel) connectUnderlayTCP6() (c underlay, err error) { } gLog.Println(LvINFO, "rtt=", time.Since(handshakeBegin)) - gLog.Println(LvDEBUG, "TCP connection ok") + gLog.Println(LvDEBUG, "TCP6 connection ok") + t.linkMode = LinkModeIPv6 return qConn, nil } @@ -551,19 +553,25 @@ func (t *P2PTunnel) heartbeatLoop() { func (t *P2PTunnel) listen() error { // notify client to connect rsp := PushConnectRsp{ - Error: 0, - Detail: "connect ok", - To: t.config.PeerNode, - From: t.pn.config.Node, - NatType: t.pn.config.natType, - HasIPv4: t.pn.config.hasIPv4, - IPv6: t.pn.config.IPv6, + Error: 0, + Detail: "connect ok", + To: t.config.PeerNode, + From: t.pn.config.Node, + NatType: t.pn.config.natType, + HasIPv4: t.pn.config.hasIPv4, + // IPv6: t.pn.config.IPv6, HasUPNPorNATPMP: t.pn.config.hasUPNPorNATPMP, FromIP: t.pn.config.publicIP, ConeNatPort: t.coneNatPort, ID: t.id, Version: OpenP2PVersion, } + // only private node set ipv6 + if t.config.fromToken == t.pn.config.Token { + t.pn.refreshIPv6() + rsp.IPv6 = t.pn.config.IPv6 + } + t.pn.push(t.config.PeerNode, MsgPushConnectRsp, rsp) gLog.Printf(LvDEBUG, "p2ptunnel wait for connecting") t.tunnelServer = true @@ -588,22 +596,12 @@ func (t *P2PTunnel) closeOverlayConns(appID uint64) { } func (t *P2PTunnel) isUnderlayServer() bool { - if t.pn.config.natType == NATNone && t.config.peerNatType != NATNone { + if (t.pn.config.hasIPv4 == 1 || t.pn.config.hasUPNPorNATPMP == 1) && (t.config.hasIPv4 != 1 || t.config.hasUPNPorNATPMP != 1) { return true } - if t.pn.config.natType != NATNone && t.config.peerNatType == NATNone { + if (t.pn.config.hasIPv4 != 1 || t.pn.config.hasUPNPorNATPMP != 1) && (t.config.hasIPv4 == 1 || t.config.hasUPNPorNATPMP == 1) { return false } // NAT or both has public IP return t.tunnelServer } - -func (t *P2PTunnel) isSupportTCP() bool { - if t.config.peerVersion == "" || compareVersion(t.config.peerVersion, LeastSupportTCPVersion) == LESS { - return false - } - if t.pn.config.natType == NATNone || t.config.peerNatType == NATNone { - return true - } - return false -} diff --git a/protocol.go b/protocol.go index 04eac44..6bff862 100644 --- a/protocol.go +++ b/protocol.go @@ -10,7 +10,7 @@ import ( "time" ) -const OpenP2PVersion = "1.5.6" +const OpenP2PVersion = "2.0.1" const ProducnName string = "openp2p" const LeastSupportTCPVersion = "1.5.0" @@ -155,6 +155,13 @@ const ( UderlayTCP = "tcp" ) +// linkmode +const ( + LinkModeUDPPunch = "udppunch" + LinkModeIPv4 = "ipv4" + LinkModeIPv6 = "ipv6" +) + func newMessage(mainType uint16, subType uint16, packet interface{}) ([]byte, error) { data, err := json.Marshal(packet) if err != nil { @@ -181,9 +188,9 @@ func nodeNameToID(name string) uint64 { type PushConnectReq struct { From string `json:"from,omitempty"` - FromToken uint64 `json:"fromToken,omitempty"` //my token + FromToken uint64 `json:"fromToken,omitempty"` // deprecated Version string `json:"version,omitempty"` - Token uint64 `json:"token,omitempty"` // totp token + Token uint64 `json:"token,omitempty"` // if public totp token ConeNatPort int `json:"coneNatPort,omitempty"` // if isPublic, is public port NatType int `json:"natType,omitempty"` HasIPv4 int `json:"hasIPv4,omitempty"` @@ -200,7 +207,7 @@ type PushConnectRsp struct { Detail string `json:"detail,omitempty"` NatType int `json:"natType,omitempty"` HasIPv4 int `json:"hasIPv4,omitempty"` - IPv6 string `json:"IPv6,omitempty"` + IPv6 string `json:"IPv6,omitempty"` // if public relay node, ipv6 not set HasUPNPorNATPMP int `json:"hasUPNPorNATPMP,omitempty"` ConeNatPort int `json:"coneNatPort,omitempty"` //it's not only cone, but also upnp or nat-pmp hole FromIP string `json:"fromIP,omitempty"` @@ -323,6 +330,7 @@ type AppInfo struct { ShareBandwidth int `json:"shareBandWidth,omitempty"` RelayNode string `json:"relayNode,omitempty"` RelayMode string `json:"relayMode,omitempty"` + LinkMode string `json:"linkMode,omitempty"` Version string `json:"version,omitempty"` RetryTime string `json:"retryTime,omitempty"` ConnectTime string `json:"connectTime,omitempty"` diff --git a/totp.go b/totp.go index 9560ad2..930c429 100644 --- a/totp.go +++ b/totp.go @@ -25,6 +25,9 @@ func VerifyTOTP(code uint64, token uint64, ts int64) bool { if code == 0 { return false } + if code == token { + return true + } if code == GenTOTP(token, ts) || code == GenTOTP(token, ts-TOTPStep) || code == GenTOTP(token, ts+TOTPStep) { return true } diff --git a/underlay_tcp6.go b/underlay_tcp6.go index 84bcc94..99e96c9 100644 --- a/underlay_tcp6.go +++ b/underlay_tcp6.go @@ -67,7 +67,7 @@ func (conn *underlayTCP6) Close() error { } func listenTCP6(port int, idleTimeout time.Duration) (*underlayTCP6, error) { - addr, _ := net.ResolveTCPAddr("tcp6", fmt.Sprintf("0.0.0.0:%d", port)) + addr, _ := net.ResolveTCPAddr("tcp6", fmt.Sprintf("[::]:%d", port)) l, err := net.ListenTCP("tcp6", addr) if err != nil { return nil, err @@ -83,9 +83,9 @@ func listenTCP6(port int, idleTimeout time.Duration) (*underlayTCP6, error) { } func dialTCP6(host string, port int) (*underlayTCP6, error) { - c, err := net.DialTimeout("tcp6", fmt.Sprintf("%s:%d", host, port), SymmetricHandshakeAckTimeout) + c, err := net.DialTimeout("tcp6", fmt.Sprintf("[%s]:%d", host, port), SymmetricHandshakeAckTimeout) if err != nil { - fmt.Printf("Dial %s:%d error:%s", host, port, err) + gLog.Printf(LvERROR, "Dial %s:%d error:%s", host, port, err) return nil, err } return &underlayTCP6{writeMtx: &sync.Mutex{}, Conn: c}, nil diff --git a/update.go b/update.go index 6a0eb42..19fc1f6 100644 --- a/update.go +++ b/update.go @@ -27,7 +27,7 @@ func update() { } goos := runtime.GOOS goarch := runtime.GOARCH - rsp, err := c.Get(fmt.Sprintf("https://openp2p.cn:27183/api/v1/update?fromver=%s&os=%s&arch=%s", OpenP2PVersion, goos, goarch)) + rsp, err := c.Get(fmt.Sprintf("https://api.openp2p.cn:27183/api/v1/update?fromver=%s&os=%s&arch=%s", OpenP2PVersion, goos, goarch)) if err != nil { gLog.Println(LvERROR, "update:query update list failed:", err) return