@@ -17,7 +17,6 @@ import (
17
17
"fmt"
18
18
"io"
19
19
"math"
20
- "runtime/debug"
21
20
"strconv"
22
21
"time"
23
22
)
@@ -28,37 +27,41 @@ import (
28
27
// Read packet to buffer 'data'
29
28
func (mc * mysqlConn ) readPacket () ([]byte , error ) {
30
29
var prevData []byte
31
- var rerr error = nil
30
+ invalid := false
31
+
32
32
for {
33
33
// read packet header
34
34
data , err := mc .packetReader .readNext (4 )
35
35
if err != nil {
36
36
if cerr := mc .canceled .Value (); cerr != nil {
37
37
return nil , cerr
38
38
}
39
- if debugTrace {
40
- debug .PrintStack ()
41
- }
42
39
mc .log (err )
43
40
mc .Close ()
44
41
return nil , ErrInvalidConn
45
42
}
46
43
47
44
// packet length [24 bit]
48
45
pktLen := int (uint32 (data [0 ]) | uint32 (data [1 ])<< 8 | uint32 (data [2 ])<< 16 )
46
+ seqNr := data [3 ]
49
47
50
48
if mc .compress {
51
49
// 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 )
54
53
}
55
- mc .compressSequence = data [ 3 ] + 1
56
- } else mc . compress {
54
+ mc .compressSequence = seqNr + 1
55
+ } else {
57
56
// 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
62
65
}
63
66
mc .sequence ++
64
67
}
@@ -72,7 +75,6 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
72
75
mc .Close ()
73
76
return nil , ErrInvalidConn
74
77
}
75
-
76
78
return prevData , nil
77
79
}
78
80
@@ -91,6 +93,10 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
91
93
if pktLen < maxPacketSize {
92
94
// zero allocations for non-split packets
93
95
if prevData == nil {
96
+ if invalid && data [0 ] != iERR {
97
+ // return sync error only for regular packet.
98
+ return nil , ErrPktSync
99
+ }
94
100
return data , nil
95
101
}
96
102
@@ -432,12 +438,9 @@ func (mc *mysqlConn) writeCommandPacket(command byte) error {
432
438
// Reset Packet Sequence
433
439
mc .resetSequenceNr ()
434
440
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 )
441
444
442
445
// Add command byte
443
446
data [4 ] = command
0 commit comments