123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- package nettools
- import (
- "crypto/tls"
- "fmt"
- "golang.org/x/net/context"
- "net"
- "strconv"
- "time"
- )
- type TlsPingResult struct {
- ConnectionTime int
- HandshakeTime int
- TLSVersion uint16
- Err error
- IP net.IP
- }
- func (tlsR *TlsPingResult) Result() int {
- return tlsR.ConnectionTime + tlsR.HandshakeTime
- }
- func (tlsR *TlsPingResult) Error() error {
- return tlsR.Err
- }
- func (tlsR *TlsPingResult) String() string {
- if tlsR.Err != nil {
- return fmt.Sprintf("%s", tlsR.Err)
- } else {
- return fmt.Sprintf("%s: protocol=%s, connection=%d ms, handshake=%d ms, time=%d ms", tlsR.IP.String(), tlsVersionToString(tlsR.TLSVersion), tlsR.ConnectionTime, tlsR.HandshakeTime, tlsR.Result())
- }
- }
- type TlsPing struct {
- Host string
- Port uint16
- ConnectionTimeout time.Duration
- HandshakeTimeout time.Duration
-
- TlsVersion uint16
- Insecure bool
- IP net.IP
- }
- func (tslC *TlsPing) Ping() IPingResult {
- return tslC.PingContext(context.Background())
- }
- func (tslC *TlsPing) PingContext(ctx context.Context) IPingResult {
- ip := cloneIP(tslC.IP)
- if ip == nil {
- var err error
- ip, err = LookupFunc(tslC.Host)
- if err != nil {
- return tslC.errorResult(err)
- }
- }
- dialer := &net.Dialer{
- Timeout: tslC.ConnectionTimeout,
- KeepAlive: -1,
- }
- t0 := time.Now()
- conn, err := dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), strconv.FormatUint(uint64(tslC.Port), 10)))
- if err != nil {
- return tslC.errorResult(err)
- }
- defer conn.Close()
- t1 := time.Now()
- config := &tls.Config{
- ServerName: tslC.Host,
- MinVersion: tslC.TlsVersion,
- MaxVersion: tslC.TlsVersion,
- InsecureSkipVerify: tslC.Insecure,
- }
- client := tls.Client(conn, config)
- client.SetDeadline(time.Now().Add(tslC.HandshakeTimeout))
- err = client.Handshake()
- if err != nil {
- return tslC.errorResult(err)
- }
- defer client.Close()
- t2 := time.Now()
- return &TlsPingResult{int(t1.Sub(t0).Milliseconds()), int(t2.Sub(t1).Milliseconds()), client.ConnectionState().Version, nil, ip}
- }
- func NewTlsPing(host string, port uint16, ct, ht time.Duration) *TlsPing {
- return &TlsPing{
- Host: host,
- Port: port,
- ConnectionTimeout: ct,
- HandshakeTimeout: ht,
- }
- }
- func (tslC *TlsPing) errorResult(err error) *TlsPingResult {
- r := &TlsPingResult{}
- r.Err = err
- return r
- }
- var (
- _ IPing = (*TlsPing)(nil)
- _ IPingResult = (*TlsPingResult)(nil)
- )
|