From 9476f38f8bce4fe0b0501e2545cba36d508b49b1 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Tue, 19 Feb 2019 10:56:06 +0100 Subject: [PATCH] add tlsping utility --- infra/control/tlsping.go | 105 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 infra/control/tlsping.go diff --git a/infra/control/tlsping.go b/infra/control/tlsping.go new file mode 100644 index 000000000..0552da1d1 --- /dev/null +++ b/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 --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{})) +}