What is the best way to add a timeout when using tls.Dial in Go?
I see the net package has net.DialTimeout, but unfortunately, the tls package doesn't have a corresponding function.
I presume I should be using a context or Dialer to implement a timeout, but I'm not an expert in Go and I can't find any good examples.
(1) I found tls.DialWithDialer, but I'm not sure how to create a net.Dialer that is configured with a timeout.
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)
(2) I also found tls.DialContext, but I'm not sure how to use that to implement a timeout.
func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error)
(3) I presume it might be possible to establish an initial connection using net.DialTimeout and then upgrade the connection and continue with the TLS handshake, but I can't find any examples that show how to do that.
Any help or guidance would be appreciated.
Here is my simple program that connects to a list of servers and prints some info about the certificate chain. When a server is not responding, this program hangs for a long time. All I want to do is time out after 10 seconds.
package main
import (
"bufio"
"crypto/tls"
"fmt"
"os"
)
func main() {
port := "443"
conf := &tls.Config{
InsecureSkipVerify: true,
}
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
host := s.Text()
conn, err := tls.Dial("tcp", host+":"+port, conf)
if err != nil {
fmt.Println("Host:", host, "Dial:", err)
continue
}
defer conn.Close()
certs := conn.ConnectionState().PeerCertificates
for _, cert := range certs {
fmt.Println("Host:", host, "Issuer:", cert.Issuer)
}
}
}