Browse Source

add tlsping utility

Darien Raymond 6 years ago
parent
commit
9476f38f8b
1 changed files with 105 additions and 0 deletions
  1. 105 0
      infra/control/tlsping.go

+ 105 - 0
infra/control/tlsping.go

@@ -0,0 +1,105 @@
+package control
+
+import (
+	"crypto/tls"
+	"flag"
+	"fmt"
+	"net"
+
+	"v2ray.com/core/common"
+)
+
+type TlsPingCommand struct{}
+
+func (c *TlsPingCommand) Name() string {
+	return "tlsping"
+}
+
+func (c *TlsPingCommand) Description() Description {
+	return Description{
+		Short: "Ping the domain with TLS handshake",
+		Usage: []string{"v2ctl tlsping <domain> --ip <ip>"},
+	}
+}
+
+func (c *TlsPingCommand) Execute(args []string) error {
+	fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+	ipStr := fs.String("ip", "", "IP address of the domain")
+
+	if err := fs.Parse(args); err != nil {
+		return newError("flag parsing").Base(err)
+	}
+
+	if fs.NArg() < 1 {
+		return newError("domain not specified")
+	}
+
+	domain := fs.Arg(0)
+	fmt.Println("Tls ping: ", domain)
+
+	var ip net.IP
+	if len(*ipStr) > 0 {
+		v := net.ParseIP(*ipStr)
+		if v == nil {
+			return newError("invalid IP: ", *ipStr)
+		}
+		ip = v
+	} else {
+		v, err := net.ResolveIPAddr("ip", domain)
+		if err != nil {
+			return newError("resolve IP").Base(err)
+		}
+		ip = v.IP
+	}
+	fmt.Println("Using IP: ", ip.String())
+
+	fmt.Println("Pinging without SNI")
+	{
+		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
+		if err != nil {
+			return newError("dial tcp").Base(err)
+		}
+		tlsConn := tls.Client(tcpConn, &tls.Config{
+			InsecureSkipVerify: true,
+			NextProtos:         []string{"http/1.1"},
+			MaxVersion:         tls.VersionTLS12,
+			MinVersion:         tls.VersionTLS12,
+		})
+		err = tlsConn.Handshake()
+		if err != nil {
+			fmt.Println("Handshake failure: ", err)
+		} else {
+			fmt.Println("Handshake succeeded")
+		}
+		tlsConn.Close()
+	}
+
+	fmt.Println("Pinging with SNI")
+	{
+		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
+		if err != nil {
+			return newError("dial tcp").Base(err)
+		}
+		tlsConn := tls.Client(tcpConn, &tls.Config{
+			ServerName: domain,
+			NextProtos: []string{"http/1.1"},
+			MaxVersion: tls.VersionTLS12,
+			MinVersion: tls.VersionTLS12,
+		})
+		err = tlsConn.Handshake()
+		if err != nil {
+			fmt.Println("handshake failure: ", err)
+		} else {
+			fmt.Println("handshake succeeded")
+		}
+		tlsConn.Close()
+	}
+
+	fmt.Println("Tls ping finished")
+
+	return nil
+}
+
+func init() {
+	common.Must(RegisterCommand(&TlsPingCommand{}))
+}