1package mssql 2 3import ( 4 "fmt" 5 "net" 6 "time" 7) 8 9type timeoutConn struct { 10 c net.Conn 11 timeout time.Duration 12} 13 14func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn { 15 return &timeoutConn{ 16 c: conn, 17 timeout: timeout, 18 } 19} 20 21func (c *timeoutConn) Read(b []byte) (n int, err error) { 22 if c.timeout > 0 { 23 err = c.c.SetDeadline(time.Now().Add(c.timeout)) 24 if err != nil { 25 return 26 } 27 } 28 return c.c.Read(b) 29} 30 31func (c *timeoutConn) Write(b []byte) (n int, err error) { 32 if c.timeout > 0 { 33 err = c.c.SetDeadline(time.Now().Add(c.timeout)) 34 if err != nil { 35 return 36 } 37 } 38 return c.c.Write(b) 39} 40 41func (c timeoutConn) Close() error { 42 return c.c.Close() 43} 44 45func (c timeoutConn) LocalAddr() net.Addr { 46 return c.c.LocalAddr() 47} 48 49func (c timeoutConn) RemoteAddr() net.Addr { 50 return c.c.RemoteAddr() 51} 52 53func (c timeoutConn) SetDeadline(t time.Time) error { 54 panic("Not implemented") 55} 56 57func (c timeoutConn) SetReadDeadline(t time.Time) error { 58 panic("Not implemented") 59} 60 61func (c timeoutConn) SetWriteDeadline(t time.Time) error { 62 panic("Not implemented") 63} 64 65// this connection is used during TLS Handshake 66// TDS protocol requires TLS handshake messages to be sent inside TDS packets 67type tlsHandshakeConn struct { 68 buf *tdsBuffer 69 packetPending bool 70 continueRead bool 71} 72 73func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) { 74 if c.packetPending { 75 c.packetPending = false 76 err = c.buf.FinishPacket() 77 if err != nil { 78 err = fmt.Errorf("Cannot send handshake packet: %s", err.Error()) 79 return 80 } 81 c.continueRead = false 82 } 83 if !c.continueRead { 84 var packet packetType 85 packet, err = c.buf.BeginRead() 86 if err != nil { 87 err = fmt.Errorf("Cannot read handshake packet: %s", err.Error()) 88 return 89 } 90 if packet != packPrelogin { 91 err = fmt.Errorf("unexpected packet %d, expecting prelogin", packet) 92 return 93 } 94 c.continueRead = true 95 } 96 return c.buf.Read(b) 97} 98 99func (c *tlsHandshakeConn) Write(b []byte) (n int, err error) { 100 if !c.packetPending { 101 c.buf.BeginPacket(packPrelogin, false) 102 c.packetPending = true 103 } 104 return c.buf.Write(b) 105} 106 107func (c *tlsHandshakeConn) Close() error { 108 panic("Not implemented") 109} 110 111func (c *tlsHandshakeConn) LocalAddr() net.Addr { 112 panic("Not implemented") 113} 114 115func (c *tlsHandshakeConn) RemoteAddr() net.Addr { 116 panic("Not implemented") 117} 118 119func (c *tlsHandshakeConn) SetDeadline(t time.Time) error { 120 panic("Not implemented") 121} 122 123func (c *tlsHandshakeConn) SetReadDeadline(t time.Time) error { 124 panic("Not implemented") 125} 126 127func (c *tlsHandshakeConn) SetWriteDeadline(t time.Time) error { 128 panic("Not implemented") 129} 130 131// this connection just delegates all methods to it's wrapped connection 132// it also allows switching underlying connection on the fly 133// it is needed because tls.Conn does not allow switching underlying connection 134type passthroughConn struct { 135 c net.Conn 136} 137 138func (c passthroughConn) Read(b []byte) (n int, err error) { 139 return c.c.Read(b) 140} 141 142func (c passthroughConn) Write(b []byte) (n int, err error) { 143 return c.c.Write(b) 144} 145 146func (c passthroughConn) Close() error { 147 return c.c.Close() 148} 149 150func (c passthroughConn) LocalAddr() net.Addr { 151 panic("Not implemented") 152} 153 154func (c passthroughConn) RemoteAddr() net.Addr { 155 panic("Not implemented") 156} 157 158func (c passthroughConn) SetDeadline(t time.Time) error { 159 panic("Not implemented") 160} 161 162func (c passthroughConn) SetReadDeadline(t time.Time) error { 163 panic("Not implemented") 164} 165 166func (c passthroughConn) SetWriteDeadline(t time.Time) error { 167 panic("Not implemented") 168} 169