Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang smtp.SendMail blocking

Tags:

go

smtp

I tried to use smtp.SendMail() in a go program. However it blocks and doesn't return until it times out. This prevents me from finding out what is wrong.

My code:

to := []string{"[email protected]"}
err := smtp.SendMail("smtp.web.de:25", smtp.CRAMMD5Auth("[email protected]", "password"), "[email protected]", to, []byte("hi"))
if err != nil {
    fmt.Println(err)
}else{
    fmt.Println("Success")
}

After a long time I get the following error:

dial tcp 213.165.67.124:25: connection timed out

Any ideas what might be the real problem?

like image 826
user2089648 Avatar asked Nov 27 '22 08:11

user2089648


1 Answers

SendMail dial smtp server uses non-tls tcp connection, maybe your smtp server default uses tcp connection with ssl, not support STARTTLS extension. Client send STARTTLS commond and server will not reply, so now is blocking.

func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
    ......

    if ok, _ := c.Extension("STARTTLS"); ok {
        config := &tls.Config{ServerName: c.serverName}
        if testHookStartTLS != nil {
            testHookStartTLS(config)
        }
        if err = c.StartTLS(config); err != nil {
            return err
        }
    }
    ......
}

Now you can dail smtp server with tls and this is not blocking, detail see example code, or use non-tls port.

// SendMailTLS connects to the server at addr, default use TLS
func SendMailTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) error {
    ......
    tlsconfig := &tls.Config{ServerName: host}
    if err = validateLine(from); err != nil {
        return err
    }
    ......
    conn, err := tls.Dial("tcp", addr, tlsconfig)
    if err != nil {
        return err
    }
    defer conn.Close()
    c, err := smtp.NewClient(conn, host)
    ......
like image 103
Yoock Avatar answered Dec 06 '22 07:12

Yoock