See: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
()
| 22 | |
| 23 | // See: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake |
| 24 | func (c *Conn) readInitialHandshake() error { |
| 25 | data, err := c.ReadPacket() |
| 26 | if err != nil { |
| 27 | return errors.Trace(err) |
| 28 | } |
| 29 | |
| 30 | if data[0] == ERR_HEADER { |
| 31 | return errors.Annotate(c.handleErrorPacket(data), "read initial handshake error") |
| 32 | } |
| 33 | |
| 34 | if data[0] < MinProtocolVersion { |
| 35 | return errors.Errorf("invalid protocol version %d, must >= 10", data[0]) |
| 36 | } |
| 37 | |
| 38 | // skip mysql version |
| 39 | // mysql version end with 0x00 |
| 40 | pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 |
| 41 | |
| 42 | // connection id length is 4 |
| 43 | c.connectionID = binary.LittleEndian.Uint32(data[pos : pos+4]) |
| 44 | pos += 4 |
| 45 | |
| 46 | c.salt = []byte{} |
| 47 | c.salt = append(c.salt, data[pos:pos+8]...) |
| 48 | |
| 49 | // skip filter |
| 50 | pos += 8 + 1 |
| 51 | |
| 52 | // capability lower 2 bytes |
| 53 | c.capability = uint32(binary.LittleEndian.Uint16(data[pos : pos+2])) |
| 54 | // check protocol |
| 55 | if c.capability&CLIENT_PROTOCOL_41 == 0 { |
| 56 | return errors.New("the MySQL server can not support protocol 41 and above required by the client") |
| 57 | } |
| 58 | if c.capability&CLIENT_SSL == 0 && c.tlsConfig != nil { |
| 59 | return errors.New("the MySQL Server does not support TLS required by the client") |
| 60 | } |
| 61 | pos += 2 |
| 62 | |
| 63 | if len(data) > pos { |
| 64 | // skip server charset |
| 65 | // c.charset = data[pos] |
| 66 | pos += 1 |
| 67 | |
| 68 | c.status = binary.LittleEndian.Uint16(data[pos : pos+2]) |
| 69 | pos += 2 |
| 70 | // capability flags (upper 2 bytes) |
| 71 | c.capability = uint32(binary.LittleEndian.Uint16(data[pos:pos+2]))<<16 | c.capability |
| 72 | pos += 2 |
| 73 | |
| 74 | // skip auth data len or [00] |
| 75 | // skip reserved (all [00]) |
| 76 | pos += 10 + 1 |
| 77 | |
| 78 | // The documentation is ambiguous about the length. |
| 79 | // The official Python library uses the fixed length 12 |
| 80 | // mysql-proxy also use 12 |
| 81 | // which is not documented but seems to work. |
no test coverage detected