tcp punch
This commit is contained in:
@@ -6,12 +6,55 @@ import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
reuse "github.com/libp2p/go-reuseport"
|
||||
)
|
||||
|
||||
var echoConn *net.UDPConn
|
||||
|
||||
func natTCP(serverHost string, serverPort int, localPort int) (publicIP string, publicPort int) {
|
||||
// dialer := &net.Dialer{
|
||||
// LocalAddr: &net.TCPAddr{
|
||||
// IP: net.ParseIP("0.0.0.0"),
|
||||
// Port: localPort,
|
||||
// },
|
||||
// }
|
||||
conn, err := reuse.Dial("tcp4", fmt.Sprintf("%s:%d", "0.0.0.0", localPort), fmt.Sprintf("%s:%d", serverHost, serverPort))
|
||||
// conn, err := net.Dial("tcp4", fmt.Sprintf("%s:%d", serverHost, serverPort))
|
||||
if err != nil {
|
||||
fmt.Printf("Dial tcp4 %s:%d error:%s", serverHost, serverPort, err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
_, wrerr := conn.Write([]byte("1"))
|
||||
if wrerr != nil {
|
||||
fmt.Printf("Write error: %s\n", wrerr)
|
||||
return
|
||||
}
|
||||
b := make([]byte, 1000)
|
||||
conn.SetReadDeadline(time.Now().Add(time.Second * 5))
|
||||
n, rderr := conn.Read(b)
|
||||
if rderr != nil {
|
||||
fmt.Printf("Read error: %s\n", rderr)
|
||||
return
|
||||
}
|
||||
arr := strings.Split(string(b[:n]), ":")
|
||||
if len(arr) < 2 {
|
||||
return
|
||||
}
|
||||
publicIP = arr[0]
|
||||
port, _ := strconv.ParseInt(arr[1], 10, 32)
|
||||
publicPort = int(port)
|
||||
return
|
||||
|
||||
}
|
||||
func natTest(serverHost string, serverPort int, localPort int, echoPort int) (publicIP string, hasPublicIP int, hasUPNPorNATPMP int, publicPort int, err error) {
|
||||
conn, err := net.ListenPacket("udp", fmt.Sprintf(":%d", localPort))
|
||||
if err != nil {
|
||||
gLog.Println(LvERROR, "natTest listen udp error:", err)
|
||||
return "", 0, 0, 0, err
|
||||
}
|
||||
defer conn.Close()
|
||||
@@ -48,7 +91,7 @@ func natTest(serverHost string, serverPort int, localPort int, echoPort int) (pu
|
||||
if i == 1 {
|
||||
// test upnp or nat-pmp
|
||||
nat, err := Discover()
|
||||
if err != nil {
|
||||
if err != nil || nat == nil {
|
||||
gLog.Println(LvDEBUG, "could not perform UPNP discover:", err)
|
||||
break
|
||||
}
|
||||
@@ -59,10 +102,12 @@ func natTest(serverHost string, serverPort int, localPort int, echoPort int) (pu
|
||||
}
|
||||
log.Println("PublicIP:", ext)
|
||||
|
||||
externalPort, err := nat.AddPortMapping("udp", echoPort, echoPort, "openp2p", 60)
|
||||
externalPort, err := nat.AddPortMapping("udp", echoPort, echoPort, "openp2p", 30)
|
||||
if err != nil {
|
||||
gLog.Println(LvDEBUG, "could not add udp UPNP port mapping", externalPort)
|
||||
break
|
||||
} else {
|
||||
nat.AddPortMapping("tcp", echoPort, echoPort, "openp2p", 604800)
|
||||
}
|
||||
}
|
||||
gLog.Printf(LvDEBUG, "public ip test start %s:%d", natRsp.IP, echoPort)
|
||||
@@ -98,14 +143,22 @@ func natTest(serverHost string, serverPort int, localPort int, echoPort int) (pu
|
||||
|
||||
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)
|
||||
localPort := int(rand.Uint32()%15000 + 50000)
|
||||
echoPort := P2PNetworkInstance(nil).config.TCPPort
|
||||
go echo(echoPort)
|
||||
// _, natPort := natTCP(host, 27181, localPort)
|
||||
// gLog.Println(LvINFO, "nattcp:", natPort)
|
||||
// _, natPort = natTCP(host, 27180, localPort)
|
||||
// gLog.Println(LvINFO, "nattcp:", natPort)
|
||||
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, hasIPv4, hasUPNPorNATPMP, err
|
||||
}
|
||||
if echoConn != nil {
|
||||
echoConn.Close()
|
||||
echoConn = nil
|
||||
}
|
||||
// if hasPublicIP == 1 || hasUPNPorNATPMP == 1 {
|
||||
// return ip1, NATNone, hasUPNPorNATPMP, nil
|
||||
// }
|
||||
@@ -122,18 +175,19 @@ func getNATType(host string, udp1 int, udp2 int) (publicIP string, NATType int,
|
||||
}
|
||||
|
||||
func echo(echoPort int) {
|
||||
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: echoPort})
|
||||
var err error
|
||||
echoConn, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: echoPort})
|
||||
if err != nil {
|
||||
gLog.Println(LvERROR, "echo server listen error:", err)
|
||||
return
|
||||
}
|
||||
buf := make([]byte, 1600)
|
||||
defer conn.Close()
|
||||
// close outside for breaking the ReadFromUDP
|
||||
// wait 5s for echo testing
|
||||
conn.SetReadDeadline(time.Now().Add(time.Second * 30))
|
||||
n, addr, err := conn.ReadFromUDP(buf)
|
||||
echoConn.SetReadDeadline(time.Now().Add(time.Second * 30))
|
||||
n, addr, err := echoConn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
conn.WriteToUDP(buf[0:n], addr)
|
||||
echoConn.WriteToUDP(buf[0:n], addr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user