shranet
shranet

Reputation: 143

Cannot convert *tls.listener to *net.TCPListener on golang

I created a TLS server on GO.

func main() {
    Log("Hello server!")

    cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        Log("server: loadkeys: ", err);
        return;
    }

    config := tls.Config{Certificates: []tls.Certificate{cert}}
    config.Rand = rand.Reader
    service := "0.0.0.0:9988"
    listener, err := tls.Listen("tcp", service, &config)
    if err != nil {
        Log("server: listen: %s", err)
        return
    }

    defer listener.Close()

    for {
        Log("Waiting for clients")

        connection, error := listener.Accept()
        if error != nil {
            Log("Client error: ", error)
        } else {
            //connection.SetLinger(0) //error here
            go ClientHandler(connection)
        }
    }
}

I cannot call SetLinger function, because tls.Listen function returns net.Listener. I need net.TCPListener.

I tried:

tpcListener := listener.(*net.TCPListener)

Error: panic: interface conversion: net.Listener is *tls.listener, not *net.TCPListener

There is ListenTCP on net package but there is not ListenTCP on tls package.

Upvotes: 2

Views: 2386

Answers (2)

Andrew Arrow
Andrew Arrow

Reputation: 4575

The solution is change:

listener, err := tls.Listen("tcp", service, &config)

to

listener, err := net.Listen("tcp", service)

Then you can call

 listener.(*net.TCPListener).SetDeadline(...)
 connection, err := listener.Accept()
 connection.(*net.TCPConn).SetLinger(9)
 tlsConn := tls.Server(conn, tlsConfig)

Upvotes: 0

Dave C
Dave C

Reputation: 7878

You explicitly mention SetLinger but that's called on a TCPConn not on a TCPListener. Have you checked if the accepted net.Conn can be asserted to *net.TCPConn?


The crypto/tls package implements the net.Listener interface via a non-exported type so you cannot access the "inner" listener that way.

If you really need a net.TCPListener: As with all the other Go standard packages that provide convenience functions that create listeners for you, there are lower level functions that let you create your own. So call net.ListenTCP, then whatever methods you like on it, then pass that to the tls package via tls.NewListener. See the source for crypto/tls's Listen for further guidance.

Upvotes: 3

Related Questions