@@ -17,7 +17,6 @@ import (
1717 "fmt"
1818 "io"
1919 "math"
20- "runtime/debug"
2120 "strconv"
2221 "time"
2322)
@@ -28,37 +27,41 @@ import (
2827// Read packet to buffer 'data'
2928func (mc * mysqlConn ) readPacket () ([]byte , error ) {
3029 var prevData []byte
31- var rerr error = nil
30+ invalid := false
31+
3232 for {
3333 // read packet header
3434 data , err := mc .packetReader .readNext (4 )
3535 if err != nil {
3636 if cerr := mc .canceled .Value (); cerr != nil {
3737 return nil , cerr
3838 }
39- if debugTrace {
40- debug .PrintStack ()
41- }
4239 mc .log (err )
4340 mc .Close ()
4441 return nil , ErrInvalidConn
4542 }
4643
4744 // packet length [24 bit]
4845 pktLen := int (uint32 (data [0 ]) | uint32 (data [1 ])<< 8 | uint32 (data [2 ])<< 16 )
46+ seqNr := data [3 ]
4947
5048 if mc .compress {
5149 // MySQL and MariaDB doesn't check packet nr in compressed packet.
52- if debugTrace && data [3 ] != mc .compressSequence {
53- mc .cfg .Logger .Print
50+ if debugTrace && seqNr != mc .compressSequence {
51+ mc .logf ("[debug] mismatched compression sequence nr: expected: %v, got %v" ,
52+ mc .compressSequence , seqNr )
5453 }
55- mc .compressSequence = data [ 3 ] + 1
56- } else mc . compress {
54+ mc .compressSequence = seqNr + 1
55+ } else {
5756 // check packet sync [8 bit]
58- if data [3 ] != mc .sequence {
59- mc .cfg .Logger .Print (fmt .Sprintf ("[warn] unexpected seq nr: expected %v, got %v" , mc .sequence , data [3 ]))
60- mc .invalid = true
61- rerr = ErrInvalidConn
57+ if seqNr != mc .sequence {
58+ mc .logf ("[warn] unexpected seq nr: expected %v, got %v" , mc .sequence , seqNr )
59+ // For large packets, we stop reading as soon as sync error.
60+ if len (prevData ) > 0 {
61+ return nil , ErrPktSyncMul
62+ }
63+ // TODO(methane): report error when the packet is not an error packet.
64+ invalid = true
6265 }
6366 mc .sequence ++
6467 }
@@ -72,7 +75,6 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
7275 mc .Close ()
7376 return nil , ErrInvalidConn
7477 }
75-
7678 return prevData , nil
7779 }
7880
@@ -91,6 +93,10 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
9193 if pktLen < maxPacketSize {
9294 // zero allocations for non-split packets
9395 if prevData == nil {
96+ if invalid && data [0 ] != iERR {
97+ // return sync error only for regular packet.
98+ return nil , ErrPktSync
99+ }
94100 return data , nil
95101 }
96102
@@ -432,12 +438,9 @@ func (mc *mysqlConn) writeCommandPacket(command byte) error {
432438 // Reset Packet Sequence
433439 mc .resetSequenceNr ()
434440
435- data , err := mc .buf .takeSmallBuffer (4 + 1 )
436- if err != nil {
437- // cannot take the buffer. Something must be wrong with the connection
438- mc .log (err )
439- return errBadConnNoWrite
440- }
441+ // We do not use mc.buf because this function is used by mc.Close()
442+ // and mc.Close() could be used when some error happend during read.
443+ data := make ([]byte , 5 )
441444
442445 // Add command byte
443446 data [4 ] = command
0 commit comments