@@ -16,6 +16,10 @@ import (
16
16
"fmt"
17
17
"io"
18
18
"math"
19
+ "os"
20
+ "path"
21
+ "runtime"
22
+ "strconv"
19
23
"time"
20
24
)
21
25
@@ -214,6 +218,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
214
218
clientLongPassword |
215
219
clientTransactions |
216
220
clientLocalFiles |
221
+ clientConnectAttrs |
217
222
mc .flags & clientLongFlag
218
223
219
224
if mc .cfg .clientFoundRows {
@@ -228,7 +233,22 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
228
233
// User Password
229
234
scrambleBuff := scramblePassword (cipher , []byte (mc .cfg .passwd ))
230
235
236
+ attrs := make (map [string ]string )
237
+ attrs ["_os" ] = runtime .GOOS
238
+ attrs ["_client_name" ] = "Go MySQL Driver"
239
+ attrs ["_pid" ] = strconv .Itoa (os .Getpid ())
240
+ attrs ["_platform" ] = runtime .GOARCH
241
+ attrs ["program_name" ] = path .Base (os .Args [0 ])
242
+
243
+ attrlen := 0
244
+ for attrname , attrvalue := range attrs {
245
+ attrlen += len (attrname ) + len (attrvalue )
246
+ // one byte to store attrname length and one byte to store attrvalue length
247
+ attrlen += 2
248
+ }
249
+
231
250
pktLen := 4 + 4 + 1 + 23 + len (mc .cfg .user ) + 1 + 1 + len (scrambleBuff )
251
+ pktLen += attrlen + 1 // one byte to store the total length of attrs
232
252
233
253
// To specify a db name
234
254
if n := len (mc .cfg .dbname ); n > 0 {
@@ -295,6 +315,19 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
295
315
pos += copy (data [pos :], mc .cfg .dbname )
296
316
data [pos ] = 0x00
297
317
}
318
+ pos ++
319
+
320
+ // Connection attributes
321
+ data [pos ] = byte (attrlen )
322
+ pos ++
323
+
324
+ for attrname , attrvalue := range attrs {
325
+ data [pos ] = byte (len (attrname ))
326
+ pos += 1 + copy (data [pos + 1 :], attrname )
327
+
328
+ data [pos ] = byte (len (attrvalue ))
329
+ pos += 1 + copy (data [pos + 1 :], attrvalue )
330
+ }
298
331
299
332
// Send Auth packet
300
333
return mc .writePacket (data )
0 commit comments