func (c *CryptoConn) SetReadDeadline(t time.Time) error {
	return c.Conn.SetReadDeadline(t)
}
SetReadDeadline sets the read deadline on the underlying connection.
A zero value for t means Read will not time out.
package etls
import (
	"bytes"
	"io"
	"net"
	"time"
	"github.com/pkg/errors"
	"github.com/SQLess/SQLess/conf"
	"github.com/SQLess/SQLess/utils/log"
)
const (
	MagicSize = 2
)
var (
	MagicBytes = [MagicSize]byte{0xC0, 0x4E}
)
type CryptoConn struct {
	net.Conn
	*Cipher
}
func NewConn(c net.Conn, cipher *Cipher) *CryptoConn {
	return &CryptoConn{
		Conn:   c,
		Cipher: cipher,
	}
}
func Dial(network, address string, cipher *Cipher) (c *CryptoConn, err error) {
	conn, err := net.DialTimeout(network, address, conf.TCPDialTimeout)
	if err != nil {
		log.WithField("addr", address).WithError(err).Error("connect failed")
		return
	}
	c = NewConn(conn, cipher)
	return
}
func (c *CryptoConn) Read(b []byte) (n int, err error) {
	if c.decStream == nil {
		buf := make([]byte, c.info.ivLen+MagicSize)
		if _, err = io.ReadFull(c.Conn, buf); err != nil {
			log.WithError(err).Info("read full failed")
			return
		}
		iv := buf[:c.info.ivLen]
		header := buf[c.info.ivLen:]
		if err = c.initDecrypt(iv); err != nil {
			return
		}
		c.decrypt(header, header)
		if !bytes.Equal(header[:MagicSize], MagicBytes[:]) {
			err = errors.New("bad stream ETLS header")
			return
		}
	}
	cipherData := make([]byte, len(b))
	n, err = c.Conn.Read(cipherData)
	if err != nil {
		return
	}
	if n > 0 {
		c.decrypt(b[0:n], cipherData[0:n])
	}
	return
}
func (c *CryptoConn) Write(b []byte) (n int, err error) {
	var iv []byte
	if c.encStream == nil {
		iv, err = c.initEncrypt()
		if err != nil {
			return
		}
	}
	if iv != nil {
		ivHeader := make([]byte, len(iv)+MagicSize)
		copy(ivHeader, iv)
		c.encrypt(ivHeader[len(iv):], MagicBytes[:])
		_, err = c.Conn.Write(ivHeader)
		if err != nil {
			return
		}
	}
	cipherData := make([]byte, len(b))
	c.encrypt(cipherData, b)
	n, err = c.Conn.Write(cipherData)
	return
}
func (c *CryptoConn) Close() error {
	if c.Conn == nil {
		return nil
	}
	return c.Conn.Close()
}
func (c *CryptoConn) LocalAddr() net.Addr {
	return c.Conn.LocalAddr()
}
func (c *CryptoConn) RemoteAddr() net.Addr {
	return c.Conn.RemoteAddr()
}
func (c *CryptoConn) SetDeadline(t time.Time) error {
	return c.Conn.SetDeadline(t)
}