Skip to content

Commit 54f45ed

Browse files
Implemented rest of packet string.
1 parent d7fe8c2 commit 54f45ed

File tree

5 files changed

+121
-84
lines changed

5 files changed

+121
-84
lines changed

binlog/authentication.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ const SHA2_FAST_AUTH_SUCCESS = 0x03
1111
const SHA2_PERFORM_FULL_AUTHENTICATION = 0x04
1212

1313
type AuthMoreDataPacket struct {
14-
PacketHeader
14+
*PacketHeader
1515
Data uint64
1616
}
1717

18-
func (c *Conn) decodeAuthMoreDataResponsePacket(ph PacketHeader) (*AuthMoreDataPacket, error) {
18+
func (c *Conn) decodeAuthMoreDataResponsePacket(ph *PacketHeader) (*AuthMoreDataPacket, error) {
1919
md := AuthMoreDataPacket{}
2020
md.PacketHeader = ph
2121
md.Data = c.getInt(TypeFixedInt, 1)

binlog/binlog.go

+34-15
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,50 @@
11
package binlog
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
)
46

5-
func (c *Conn) startBinLogStream() error {
6-
bldc := &BinLogDumpCommand{
7+
func (c *Conn) registerAsSlave() error {
8+
brsc := &BinlogRegisterSlaveCommand{
9+
Status: COMMAND_REGISTER_SLAVE,
10+
ServerId: c.Config.ServerId,
11+
Hostname: "",
12+
User: "",
13+
Password: "",
14+
Port: 0,
15+
ReplRank: 1,
16+
MasterId: 0,
17+
}
18+
19+
return c.writeBinlogRegisterSlaveCommand(brsc)
20+
}
21+
22+
func (c *Conn) startBinlogStream() error {
23+
bldc := &BinlogDumpCommand{
724
Status: COMMAND_BIN_LOG_DUMP,
825
Position: 120,
926
Flags: BINLOG_DUMP_NON_BLOCK,
1027
ServerId: c.Config.ServerId,
11-
Filename: c.Config.BinLogFile,
28+
Filename: c.Config.BinlogFile,
1229
}
1330

14-
return c.writeBinLogDumpCommand(bldc)
31+
return c.writeBinlogDumpCommand(bldc)
1532
}
1633

1734
func (c *Conn) listenForBinlog() error {
18-
res, err := c.listen()
19-
if err != nil {
20-
return err
35+
for {
36+
p, err := c.readPacket()
37+
if err != nil {
38+
if err.Error() == "EOF" {
39+
continue
40+
} else {
41+
return err
42+
}
43+
} else {
44+
kp := p.(*OKPacket)
45+
fmt.Printf("kp = %+v\n", kp)
46+
}
2147
}
2248

23-
fmt.Printf("res = %+v\n", res)
24-
25-
// err = c.listenForBinlog()
26-
// if err != nil {
27-
// return err
28-
// }
29-
3049
return nil
3150
}

binlog/commands.go

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
11
package binlog
22

3-
const COMMAND_BIN_LOG_DUMP = 0x12
43
const BINLOG_DUMP_NON_BLOCK = 0x01
4+
const COMMAND_BIN_LOG_DUMP = 0x12
5+
const COMMAND_REGISTER_SLAVE = 0x15
6+
7+
type BinlogRegisterSlaveCommand struct {
8+
Status uint64
9+
ServerId uint64
10+
Hostname string // Length Encoded
11+
User string // Length Encoded
12+
Password string // Length Encoded
13+
Port uint64
14+
ReplRank uint64
15+
MasterId uint64
16+
}
17+
18+
func (c *Conn) writeBinlogRegisterSlaveCommand(brsc *BinlogRegisterSlaveCommand) error {
19+
c.putInt(TypeFixedInt, brsc.Status, 1)
20+
c.putInt(TypeFixedInt, brsc.ServerId, 4)
21+
c.putString(TypeLenEncString, brsc.Hostname)
22+
c.putString(TypeLenEncString, brsc.User)
23+
c.putString(TypeLenEncString, brsc.Password)
24+
c.putInt(TypeLenEncInt, brsc.Port, 2)
25+
c.putInt(TypeLenEncInt, brsc.ReplRank, 4)
26+
c.putInt(TypeLenEncInt, brsc.MasterId, 4)
27+
28+
if c.Flush() != nil {
29+
return c.Flush()
30+
}
31+
32+
return nil
33+
}
534

6-
type BinLogDumpCommand struct {
35+
type BinlogDumpCommand struct {
736
Status uint64
837
Position uint64
938
Flags uint64
1039
ServerId uint64
1140
Filename string
1241
}
1342

14-
func (c *Conn) writeBinLogDumpCommand(bldc *BinLogDumpCommand) error {
43+
func (c *Conn) writeBinlogDumpCommand(bldc *BinlogDumpCommand) error {
1544
c.putInt(TypeFixedInt, bldc.Status, 1)
1645
c.putInt(TypeFixedInt, bldc.Position, 4)
1746
c.putInt(TypeFixedInt, bldc.Flags, 2)

binlog/connection.go

+52-63
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type Config struct {
5757
SSLKey string `json:"ssl-key"`
5858
VerifyCert bool `json:"verify-cert"`
5959
ServerId uint64 `json:"server-id"`
60-
BinLogFile string `json:"binlog-file"`
60+
BinlogFile string `json:"binlog-file"`
6161
Timeout time.Duration
6262
}
6363

@@ -89,6 +89,8 @@ type Conn struct {
8989
writeBuf *bytes.Buffer
9090
StausFlags *StatusFlags
9191
Listener *net.Listener
92+
packetHeader *PacketHeader
93+
scanPos uint64
9294
}
9395

9496
func newBinlogConn(config *Config) Conn {
@@ -168,40 +170,34 @@ func (d Driver) Open(dsn string) (driver.Conn, error) {
168170
}
169171

170172
// Listen for auth response.
171-
r, err := c.listen()
172-
switch r.(type) {
173-
case *OKPacket: // Login successful.
174-
// Reset sequence to 0 now that connection phase is over
175-
// and command phase has started.
176-
c.sequenceId = 0
177-
178-
// Tell server to stream binlog.
179-
err = c.startBinLogStream()
180-
if err != nil {
181-
return nil, err
182-
}
173+
_, err = c.readPacket()
174+
if err != nil {
175+
return nil, err
176+
}
183177

184-
err = c.listenForBinlog()
185-
if err != nil {
186-
return nil, err
187-
}
188-
case *ErrorPacket: // Bad login.
189-
ep := r.(*ErrorPacket)
190-
em := fmt.Sprintf("Error %d: %s", ep.ErrorCode, ep.ErrorMessage)
191-
err = errors.New(em)
178+
// Auth was successful.
179+
c.sequenceId = 0
180+
181+
// Register as a slave
182+
err = c.registerAsSlave()
183+
if err != nil {
184+
return nil, err
185+
}
186+
187+
_, err = c.readPacket()
188+
if err != nil {
192189
return nil, err
193-
case *AuthMoreDataPacket:
194-
panic(errors.New("Unexpected AuthMoreDataPacket"))
195190
}
196191

197192
return c, err
198193
}
199194

200-
func (c *Conn) listen() (interface{}, error) {
195+
func (c *Conn) readPacket() (interface{}, error) {
201196
ph, err := c.getPacketHeader()
202197
if err != nil {
203198
return nil, err
204199
}
200+
205201
c.sequenceId++
206202

207203
var res interface{}
@@ -222,7 +218,6 @@ func (c *Conn) listen() (interface{}, error) {
222218
return nil, c.Flush()
223219
}
224220
}
225-
226221
case StatusEOF:
227222
fallthrough
228223
case StatusOK:
@@ -236,12 +231,11 @@ func (c *Conn) listen() (interface{}, error) {
236231
return nil, err
237232
}
238233

239-
err = errors.New(
240-
fmt.Sprintf(
241-
"Error %d: %s",
242-
res.(*ErrorPacket).ErrorCode,
243-
res.(*ErrorPacket).ErrorMessage,
244-
))
234+
err = fmt.Errorf(
235+
"Error %d: %s",
236+
res.(*ErrorPacket).ErrorCode,
237+
res.(*ErrorPacket).ErrorMessage,
238+
)
245239

246240
return res, err
247241
}
@@ -260,18 +254,27 @@ type PacketHeader struct {
260254
Status uint64
261255
}
262256

263-
func (c *Conn) getPacketHeader() (PacketHeader, error) {
257+
func (c *Conn) getPacketHeader() (*PacketHeader, error) {
264258
ph := PacketHeader{}
265259
ph.Length = c.getInt(TypeFixedInt, 3)
260+
261+
if ph.Length == 0 {
262+
err := errors.New("EOF")
263+
return nil, err
264+
}
265+
266266
ph.SequenceID = c.getInt(TypeFixedInt, 1)
267267
ph.Status = c.getInt(TypeFixedInt, 1)
268268

269269
err := c.scanner.Err()
270270
if err != nil {
271-
return ph, err
271+
return &ph, err
272272
}
273273

274-
return ph, nil
274+
c.packetHeader = &ph
275+
c.scanPos = 0
276+
277+
return &ph, nil
275278
}
276279

277280
func init() {
@@ -289,33 +292,12 @@ func (c *Conn) readBytes(l uint64) *bytes.Buffer {
289292
} else {
290293
panic(err) // @TODO Handle this gracefully.
291294
}
292-
293-
return nil
294295
}
295296

296297
b = append(b, c.scanner.Bytes()...)
297298
}
298299

299-
return bytes.NewBuffer(b)
300-
}
301-
302-
func (c *Conn) getBytesUntilEOF() *bytes.Buffer {
303-
l := uint64(1)
304-
s := c.readBytes(l)
305-
b := s.Bytes()
306-
307-
for true {
308-
if uint64(s.Len()) != l || s.Bytes()[0] == NullByte {
309-
break
310-
}
311-
312-
s := c.readBytes(uint64(l))
313-
if s == EOF || s == nil {
314-
return bytes.NewBuffer(b)
315-
}
316-
317-
b = append(b, s.Bytes()...)
318-
}
300+
c.scanPos += uint64(len(b))
319301

320302
return bytes.NewBuffer(b)
321303
}
@@ -325,7 +307,7 @@ func (c *Conn) getBytesUntilNull() *bytes.Buffer {
325307
s := c.readBytes(l)
326308
b := s.Bytes()
327309

328-
for true {
310+
for {
329311
if uint64(s.Len()) != l || s.Bytes()[0] == NullByte {
330312
break
331313
}
@@ -376,8 +358,15 @@ func (c *Conn) getString(t int, l uint64) string {
376358
}
377359

378360
func (c *Conn) decRestOfPacketString() string {
379-
b := c.getBytesUntilEOF()
380-
return string(b.Bytes())
361+
b := c.getRemainingBytes()
362+
return b.String()
363+
}
364+
365+
func (c *Conn) getRemainingBytes() *bytes.Buffer {
366+
l := (c.packetHeader.Length - 1) - c.scanPos
367+
b := c.readBytes(l)
368+
369+
return b
381370
}
382371

383372
func (c *Conn) decNullTerminatedString() string {
@@ -651,7 +640,7 @@ type StatusFlags struct {
651640
}
652641

653642
type OKPacket struct {
654-
PacketHeader
643+
*PacketHeader
655644
Header uint64
656645
AffectedRows uint64
657646
LastInsertID uint64
@@ -661,7 +650,7 @@ type OKPacket struct {
661650
SessionStateInfo string
662651
}
663652

664-
func (c *Conn) decodeOKPacket(ph PacketHeader) (*OKPacket, error) {
653+
func (c *Conn) decodeOKPacket(ph *PacketHeader) (*OKPacket, error) {
665654
op := OKPacket{}
666655
op.PacketHeader = ph
667656
op.Header = ph.Status
@@ -684,14 +673,14 @@ func (c *Conn) decodeOKPacket(ph PacketHeader) (*OKPacket, error) {
684673
}
685674

686675
type ErrorPacket struct {
687-
PacketHeader
676+
*PacketHeader
688677
ErrorCode uint64
689678
ErrorMessage string
690679
SQLStateMarker string
691680
SQLState string
692681
}
693682

694-
func (c *Conn) decodeErrorPacket(ph PacketHeader) (*ErrorPacket, error) {
683+
func (c *Conn) decodeErrorPacket(ph *PacketHeader) (*ErrorPacket, error) {
695684
ep := ErrorPacket{}
696685
ep.PacketHeader = ph
697686
ep.ErrorCode = c.getInt(TypeFixedInt, 2)

config.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
"ssl-cer": "",
1010
"ssl-ca": "/Users/josh/Sites/Certificates.pem",
1111
"verify-cert": false,
12-
"server-id": 1,
12+
"server-id": 2,
1313
"binlog-file": "mysql-bin.000004"
1414
}

0 commit comments

Comments
 (0)