func (p *Proxy) readHelloMessageWithoutTLSTermination(conn net.Conn) (*tls.ClientHelloInfo, net.Conn, error) {
	buff := new(bytes.Buffer)
	var hello *tls.ClientHelloInfo
	tlsConn := tls.Server(readOnlyConn{reader: io.TeeReader(conn, buff)}, &tls.Config{
		GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
			hello = info
			return nil, nil
		},
	})
	if err := conn.SetReadDeadline(p.cfg.Clock.Now().Add(p.cfg.ReadDeadline)); err != nil {
		return nil, nil, trace.Wrap(err)
	}

	// Following TLS handshake fails on the server side with error: "no certificates configured" after server
	// receives a TLS hello message from the client. If handshake was able to read hello message it indicates successful
	// flow otherwise TLS handshake error is returned.
	err := tlsConn.Handshake()
	if hello == nil {
		return nil, nil, trace.Wrap(err)
	}
	if err := conn.SetReadDeadline(time.Time{}); err != nil {
		return nil, nil, trace.Wrap(err)
	}
	return hello, newBufferedConn(conn, buff), nil
}
// readHelloMessageWithoutTLSTermination allows reading a ClientHelloInfo message without termination of
// incoming TLS connection. After calling readHelloMessageWithoutTLSTermination function a returned
// net.Conn should be used for further operation.
readHelloMessageWithoutTLSTermination allows reading a ClientHelloInfo message without termination of
incoming TLS connection. After calling readHelloMessageWithoutTLSTermination function a returned
net.Conn should be used for further operation.
// readHelloMessageWithoutTLSTermination allows reading a ClientHelloInfo message without termination of // incoming TLS connection . After calling readHelloMessageWithoutTLSTermination function a returned // net . Conn should be used for further operation .
func (p *Proxy) readHelloMessageWithoutTLSTermination(conn net.Conn) (*tls.ClientHelloInfo, net.Conn, error) {
	buff := new(bytes.Buffer)
	var hello *tls.ClientHelloInfo
	tlsConn := tls.Server(readOnlyConn{reader: io.TeeReader(conn, buff)}, &tls.Config{
		GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
			hello = info
			return nil, nil
		},
	})
	if err := conn.SetReadDeadline(p.cfg.Clock.Now().Add(p.cfg.ReadDeadline)); err != nil {
		return nil, nil, trace.Wrap(err)
	}
	err := tlsConn.Handshake()
	if hello == nil {
		return nil, nil, trace.Wrap(err)
	}
	if err := conn.SetReadDeadline(time.Time{}); err != nil {
		return nil, nil, trace.Wrap(err)
	}
	return hello, newBufferedConn(conn, buff), nil
}
func ( p * Proxy ) readHelloMessageWithoutTLSTermination ( conn net . Conn ) ( * tls . ClientHelloInfo , net . Conn , error ) { buff := new ( bytes . Buffer ) var hello * tls . ClientHelloInfo tlsConn := tls . Server ( readOnlyConn { reader : io . TeeReader ( conn , buff ) } , & tls . Config { GetConfigForClient : func ( info * tls . ClientHelloInfo ) ( * tls . Config , error ) { hello = info return nil , nil } , } ) if err := conn . SetReadDeadline ( p . cfg . Clock . Now ( ) . Add ( p . cfg . ReadDeadline ) ) ; err != nil { return nil , nil , trace . Wrap ( err ) } err := tlsConn . Handshake ( ) if hello == nil { return nil , nil , trace . Wrap ( err ) } if err := conn . SetReadDeadline ( time . Time { } ) ; err != nil { return nil , nil , trace . Wrap ( err ) } return hello , newBufferedConn ( conn , buff ) , nil }
readHelloMessageWithoutTLSTermination allows reading a ClientHelloInfo message without termination of
incoming TLS connection.
readHelloMessageWithoutTLSTermination allows reading a ClientHelloInfo message without termination of incoming TLS connection .
// Following TLS handshake fails on the server side with error: "no certificates configured" after server // receives a TLS hello message from the client. If handshake was able to read hello message it indicates successful // flow otherwise TLS handshake error is returned.