@@ -12,14 +12,10 @@ use log::{debug, warn};
12
12
use once_cell:: sync:: Lazy ;
13
13
use prost:: Message ;
14
14
use socket2:: SockRef ;
15
- use tokio:: io:: BufStream ;
16
15
use tokio:: sync:: { mpsc, oneshot} ;
17
16
use tokio:: {
18
- io:: { AsyncBufReadExt , AsyncReadExt , AsyncWriteExt , BufReader } ,
19
- net:: {
20
- tcp:: { OwnedReadHalf , OwnedWriteHalf } ,
21
- TcpStream ,
22
- } ,
17
+ io:: AsyncWriteExt ,
18
+ net:: TcpStream ,
23
19
task:: { self , JoinHandle } ,
24
20
} ;
25
21
use uuid:: Uuid ;
@@ -28,7 +24,7 @@ use crate::proto::common::rpc_response_header_proto::RpcStatusProto;
28
24
use crate :: proto:: common:: TokenProto ;
29
25
use crate :: proto:: hdfs:: DatanodeIdProto ;
30
26
use crate :: proto:: { common, hdfs} ;
31
- use crate :: security:: sasl:: SaslDatanodeConnection ;
27
+ use crate :: security:: sasl:: { SaslDatanodeConnection , SaslDatanodeReader , SaslDatanodeWriter } ;
32
28
use crate :: security:: sasl:: { SaslReader , SaslRpcClient , SaslWriter } ;
33
29
use crate :: security:: user:: UserInfo ;
34
30
use crate :: { HdfsError , Result } ;
@@ -182,7 +178,7 @@ impl RpcConnection {
182
178
fn start_sender ( & mut self , mut rx : mpsc:: Receiver < Vec < u8 > > , mut writer : SaslWriter ) {
183
179
task:: spawn ( async move {
184
180
while let Some ( msg) = rx. recv ( ) . await {
185
- match writer. write ( & msg) . await {
181
+ match writer. write_all ( & msg) . await {
186
182
Ok ( _) => ( ) ,
187
183
Err ( _) => break ,
188
184
}
@@ -515,10 +511,10 @@ impl Packet {
515
511
}
516
512
}
517
513
518
- #[ derive( Debug ) ]
519
514
pub ( crate ) struct DatanodeConnection {
520
515
client_name : String ,
521
- stream : BufStream < TcpStream > ,
516
+ reader : SaslDatanodeReader ,
517
+ writer : SaslDatanodeWriter ,
522
518
url : String ,
523
519
}
524
520
@@ -528,18 +524,13 @@ impl DatanodeConnection {
528
524
let url = format ! ( "{}:{}" , datanode_id. ip_addr, datanode_id. xfer_port) ;
529
525
let stream = connect ( & url) . await ?;
530
526
531
- // If the token has an identifier, we can do SASL negotation
532
- let stream = if token. identifier . is_empty ( ) {
533
- stream
534
- } else {
535
- debug ! ( "{:?}" , token) ;
536
- let sasl_connection = SaslDatanodeConnection :: create ( stream) ;
537
- sasl_connection. negotiate ( datanode_id, token) . await ?
538
- } ;
527
+ let sasl_connection = SaslDatanodeConnection :: create ( stream) ;
528
+ let ( reader, writer) = sasl_connection. negotiate ( datanode_id, token) . await ?;
539
529
540
530
let conn = DatanodeConnection {
541
531
client_name : Uuid :: new_v4 ( ) . to_string ( ) ,
542
- stream : BufStream :: new ( stream) ,
532
+ reader,
533
+ writer,
543
534
url : url. to_string ( ) ,
544
535
} ;
545
536
Ok ( conn)
@@ -550,26 +541,21 @@ impl DatanodeConnection {
550
541
op : Op ,
551
542
message : & impl Message ,
552
543
) -> Result < hdfs:: BlockOpResponseProto > {
553
- self . stream
544
+ self . writer
554
545
. write_all ( & DATA_TRANSFER_VERSION . to_be_bytes ( ) )
555
546
. await ?;
556
- self . stream . write_all ( & [ op. value ( ) ] ) . await ?;
557
- self . stream
547
+ self . writer . write_all ( & [ op. value ( ) ] ) . await ?;
548
+ self . writer
558
549
. write_all ( & message. encode_length_delimited_to_vec ( ) )
559
550
. await ?;
560
- self . stream . flush ( ) . await ?;
551
+ self . writer . flush ( ) . await ?;
561
552
562
- let buf = self . stream . fill_buf ( ) . await ?;
563
- if buf. is_empty ( ) {
564
- return Err ( std:: io:: Error :: from ( std:: io:: ErrorKind :: UnexpectedEof ) ) ?;
565
- }
566
- let msg_length = prost:: decode_length_delimiter ( buf) ?;
567
- let total_size = msg_length + prost:: length_delimiter_len ( msg_length) ;
553
+ let msg_length = self . reader . read_length_delimiter ( ) . await ?;
568
554
569
- let mut response_buf = BytesMut :: zeroed ( total_size ) ;
570
- self . stream . read_exact ( & mut response_buf) . await ?;
555
+ let mut response_buf = BytesMut :: zeroed ( msg_length ) ;
556
+ self . reader . read_exact ( & mut response_buf) . await ?;
571
557
572
- let response = hdfs:: BlockOpResponseProto :: decode_length_delimited ( response_buf. freeze ( ) ) ?;
558
+ let response = hdfs:: BlockOpResponseProto :: decode ( response_buf. freeze ( ) ) ?;
573
559
Ok ( response)
574
560
}
575
561
@@ -593,14 +579,14 @@ impl DatanodeConnection {
593
579
pub ( crate ) async fn read_packet ( & mut self ) -> Result < Packet > {
594
580
let mut payload_len_buf = [ 0u8 ; 4 ] ;
595
581
let mut header_len_buf = [ 0u8 ; 2 ] ;
596
- self . stream . read_exact ( & mut payload_len_buf) . await ?;
597
- self . stream . read_exact ( & mut header_len_buf) . await ?;
582
+ self . reader . read_exact ( & mut payload_len_buf) . await ?;
583
+ self . reader . read_exact ( & mut header_len_buf) . await ?;
598
584
599
585
let payload_length = u32:: from_be_bytes ( payload_len_buf) as usize ;
600
586
let header_length = u16:: from_be_bytes ( header_len_buf) as usize ;
601
587
602
588
let mut remaining_buf = BytesMut :: zeroed ( payload_length - 4 + header_length) ;
603
- self . stream . read_exact ( & mut remaining_buf) . await ?;
589
+ self . reader . read_exact ( & mut remaining_buf) . await ?;
604
590
605
591
let header =
606
592
hdfs:: PacketHeaderProto :: decode ( remaining_buf. split_to ( header_length) . freeze ( ) ) ?;
@@ -617,75 +603,46 @@ impl DatanodeConnection {
617
603
status : hdfs:: Status :: ChecksumOk as i32 ,
618
604
} ;
619
605
620
- self . stream
606
+ self . writer
621
607
. write_all ( & client_read_status. encode_length_delimited_to_vec ( ) )
622
608
. await ?;
623
- self . stream . flush ( ) . await ?;
609
+ self . writer . flush ( ) . await ?;
624
610
625
611
Ok ( ( ) )
626
612
}
627
613
628
614
pub ( crate ) fn split ( self ) -> ( DatanodeReader , DatanodeWriter ) {
629
- let ( reader, writer) = self . stream . into_inner ( ) . into_split ( ) ;
630
615
let reader = DatanodeReader {
631
- client_name : self . client_name . clone ( ) ,
632
- reader : BufReader :: new ( reader) ,
633
- url : self . url ,
616
+ reader : self . reader ,
634
617
} ;
635
618
let writer = DatanodeWriter {
636
- client_name : self . client_name ,
637
- writer,
619
+ writer : self . writer ,
638
620
} ;
639
621
( reader, writer)
640
622
}
641
-
642
- // For future use where we cache datanode connections
643
- #[ allow( dead_code) ]
644
- pub ( crate ) fn reunite ( reader : DatanodeReader , writer : DatanodeWriter ) -> Self {
645
- assert_eq ! ( reader. client_name, writer. client_name) ;
646
- let stream = BufStream :: new ( reader. reader . into_inner ( ) . reunite ( writer. writer ) . unwrap ( ) ) ;
647
- Self {
648
- client_name : reader. client_name ,
649
- stream,
650
- url : reader. url ,
651
- }
652
- }
653
623
}
654
624
655
625
/// A reader half of a Datanode connection used for reading acks during
656
626
/// write operations.
657
627
pub ( crate ) struct DatanodeReader {
658
- client_name : String ,
659
- reader : BufReader < OwnedReadHalf > ,
660
- url : String ,
628
+ reader : SaslDatanodeReader ,
661
629
}
662
630
663
631
impl DatanodeReader {
664
632
pub ( crate ) async fn read_ack ( & mut self ) -> Result < hdfs:: PipelineAckProto > {
665
- let buf = self . reader . fill_buf ( ) . await ?;
633
+ let ack_length = self . reader . read_length_delimiter ( ) . await ?;
666
634
667
- if buf. is_empty ( ) {
668
- // The stream has been closed
669
- return Err ( HdfsError :: DataTransferError (
670
- "Datanode connection closed while waiting for ack" . to_string ( ) ,
671
- ) ) ;
672
- }
673
-
674
- let ack_length = prost:: decode_length_delimiter ( buf) ?;
675
- let total_size = ack_length + prost:: length_delimiter_len ( ack_length) ;
676
-
677
- let mut response_buf = BytesMut :: zeroed ( total_size) ;
635
+ let mut response_buf = BytesMut :: zeroed ( ack_length) ;
678
636
self . reader . read_exact ( & mut response_buf) . await ?;
679
637
680
- let response = hdfs:: PipelineAckProto :: decode_length_delimited ( response_buf. freeze ( ) ) ?;
638
+ let response = hdfs:: PipelineAckProto :: decode ( response_buf. freeze ( ) ) ?;
681
639
Ok ( response)
682
640
}
683
641
}
684
642
685
643
/// A write half of a Datanode connection used for writing packets.
686
644
pub ( crate ) struct DatanodeWriter {
687
- client_name : String ,
688
- writer : OwnedWriteHalf ,
645
+ writer : SaslDatanodeWriter ,
689
646
}
690
647
691
648
impl DatanodeWriter {
@@ -696,8 +653,10 @@ impl DatanodeWriter {
696
653
let payload_len = ( checksum. len ( ) + data. len ( ) + 4 ) as u32 ;
697
654
let header_encoded = header. encode_to_vec ( ) ;
698
655
699
- self . writer . write_u32 ( payload_len) . await ?;
700
- self . writer . write_u16 ( header_encoded. len ( ) as u16 ) . await ?;
656
+ self . writer . write_all ( & payload_len. to_be_bytes ( ) ) . await ?;
657
+ self . writer
658
+ . write_all ( & ( header_encoded. len ( ) as u16 ) . to_be_bytes ( ) )
659
+ . await ?;
701
660
self . writer . write_all ( & header. encode_to_vec ( ) ) . await ?;
702
661
self . writer . write_all ( & checksum) . await ?;
703
662
self . writer . write_all ( & data) . await ?;
0 commit comments