Reputation: 143
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
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
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