@@ -393,13 +393,6 @@ func Connect(addr string, opts Opts) (conn *Connection, err error) {
393
393
}
394
394
}
395
395
396
- if err = conn .loadProtocolInfo (); err != nil {
397
- conn .mutex .Lock ()
398
- defer conn .mutex .Unlock ()
399
- conn .closeConnection (err , true )
400
- return nil , err
401
- }
402
-
403
396
return conn , err
404
397
}
405
398
@@ -511,6 +504,13 @@ func (conn *Connection) dial() (err error) {
511
504
conn .Greeting .Version = bytes .NewBuffer (greeting [:64 ]).String ()
512
505
conn .Greeting .auth = bytes .NewBuffer (greeting [64 :108 ]).String ()
513
506
507
+ // IPROTO_ID requests can be processed without authentication.
508
+ // https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/requests/#iproto-id
509
+ if err = conn .loadProtocolInfo (w , r ); err != nil {
510
+ connection .Close ()
511
+ return err
512
+ }
513
+
514
514
// Auth
515
515
if opts .User != "" {
516
516
scr , err := scramble (conn .Greeting .auth , opts .Pass )
@@ -590,43 +590,64 @@ func pack(h *smallWBuf, enc *encoder, reqid uint32,
590
590
return
591
591
}
592
592
593
- func (conn * Connection ) writeAuthRequest (w * bufio.Writer , scramble []byte ) (err error ) {
593
+ func (conn * Connection ) writeRequestRaw (w * bufio.Writer , req Request ,
594
+ reqName string ) (err error ) {
594
595
var packet smallWBuf
595
- req := newAuthRequest (conn .opts .User , string (scramble ))
596
596
err = pack (& packet , newEncoder (& packet ), 0 , req , ignoreStreamId , conn .Schema )
597
597
598
598
if err != nil {
599
- return errors .New ("auth : pack error " + err .Error ())
599
+ return errors .New (reqName + " : pack error " + err .Error ())
600
600
}
601
601
if err := write (w , packet .b ); err != nil {
602
- return errors .New ("auth : write error " + err .Error ())
602
+ return errors .New (reqName + " : write error " + err .Error ())
603
603
}
604
604
if err = w .Flush (); err != nil {
605
- return errors .New ("auth : flush error " + err .Error ())
605
+ return errors .New (reqName + " : flush error " + err .Error ())
606
606
}
607
607
return
608
608
}
609
609
610
- func (conn * Connection ) readAuthResponse (r io.Reader ) (err error ) {
610
+ func (conn * Connection ) writeAuthRequest (w * bufio.Writer , scramble []byte ) (err error ) {
611
+ req := newAuthRequest (conn .opts .User , string (scramble ))
612
+ return conn .writeRequestRaw (w , req , "auth" )
613
+ }
614
+
615
+ func (conn * Connection ) writeProtocolInfoRequest (w * bufio.Writer , version ProtocolVersion ,
616
+ features []ProtocolFeature ) (err error ) {
617
+ req := newProtocolInfoRequest (version , features )
618
+ return conn .writeRequestRaw (w , req , "iproto id" )
619
+ }
620
+
621
+ func (conn * Connection ) readResponseRaw (r io.Reader ,
622
+ reqName string ) (resp Response , err error ) {
611
623
respBytes , err := conn .read (r )
612
624
if err != nil {
613
- return errors .New ("auth : read error " + err .Error ())
625
+ return resp , errors .New (reqName + " : read error " + err .Error ())
614
626
}
615
- resp : = Response {buf : smallBuf {b : respBytes }}
627
+ resp = Response {buf : smallBuf {b : respBytes }}
616
628
err = resp .decodeHeader (conn .dec )
617
629
if err != nil {
618
- return errors .New ("auth : decode response header error " + err .Error ())
630
+ return resp , errors .New (reqName + " : decode response header error " + err .Error ())
619
631
}
620
632
err = resp .decodeBody ()
621
633
if err != nil {
622
634
switch err .(type ) {
623
635
case Error :
624
- return err
636
+ return resp , err
625
637
default :
626
- return errors .New ("auth : decode response body error " + err .Error ())
638
+ return resp , errors .New (reqName + " : decode response body error " + err .Error ())
627
639
}
628
640
}
629
- return
641
+ return resp , nil
642
+ }
643
+
644
+ func (conn * Connection ) readAuthResponse (r io.Reader ) (err error ) {
645
+ _ , err = conn .readResponseRaw (r , "auth" )
646
+ return err
647
+ }
648
+
649
+ func (conn * Connection ) readProtocolInfoResponse (r io.Reader ) (resp Response , err error ) {
650
+ return conn .readResponseRaw (r , "iproto id" )
630
651
}
631
652
632
653
func (conn * Connection ) createConnection (reconnect bool ) (err error ) {
@@ -696,10 +717,6 @@ func (conn *Connection) reconnect(neterr error, c net.Conn) {
696
717
conn .closeConnection (neterr , false )
697
718
if err := conn .createConnection (true ); err != nil {
698
719
conn .closeConnection (err , true )
699
- } else {
700
- if err = conn .loadProtocolInfo (); err != nil {
701
- conn .closeConnection (err , true )
702
- }
703
720
}
704
721
}
705
722
} else {
@@ -1180,15 +1197,21 @@ func (conn *Connection) NewStream() (*Stream, error) {
1180
1197
// loadProtocolInfo sends info about client protocol,
1181
1198
// receives info about server protocol in response
1182
1199
// and store in in connection serverProtocolInfo.
1183
- func (conn * Connection ) loadProtocolInfo () error {
1200
+ func (conn * Connection ) loadProtocolInfo (w * bufio. Writer , r * bufio. Reader ) error {
1184
1201
var ok bool
1202
+ var resp Response
1203
+ var err error
1204
+
1205
+ err = conn .writeProtocolInfoRequest (w , ClientProtocolVersion , ClientProtocolFeatures )
1206
+ if err != nil {
1207
+ return err
1208
+ }
1185
1209
1186
- resp , err := conn .exchangeProtocolInfo (
1187
- ClientProtocolVersion ,
1188
- ClientProtocolFeatures )
1210
+ resp , err = conn .readProtocolInfoResponse (r )
1189
1211
1190
1212
if err != nil {
1191
- if resp .Code == ErrUnknownRequestType {
1213
+ tarantoolError , ok := err .(Error )
1214
+ if ok && tarantoolError .Code == ErrUnknownRequestType {
1192
1215
// IPROTO_ID requests are not supported by server.
1193
1216
conn .serverProtocolInfo = protocolInfo {
1194
1217
version : ProtocolVersionUnsupported ,
0 commit comments