8888	// errGarbageTooLarge is returned if a caller attempts to send garbage 
8989	// larger than normal. 
9090	errGarbageTooLarge  =  fmt .Errorf ("garbage too large" )
91+ 
92+ 	// ErrShouldDowngradeToV1 is returned when we send the peer our 
93+ 	// ellswift key and they immediately hang up. This indicates that they 
94+ 	// don't understand v2 transport and interpreted the 64-byte key as a 
95+ 	// v1 message header + message. This will (always?) decode to an 
96+ 	// invalid command and checksum. The caller should try connecting to 
97+ 	// the peer with the OG v1 transport. 
98+ 	ErrShouldDowngradeToV1  =  fmt .Errorf ("should downgrade to v1" )
9199)
92100
93101// Peer defines the components necessary for sending/receiving data over the v2 
@@ -376,7 +384,7 @@ func (p *Peer) RespondV2Handshake(garbageLen int, net wire.BitcoinNet) error {
376384			len (p .receivedPrefix ), len (v1Prefix ))
377385
378386		var  receiveBytes  []byte 
379- 		receiveBytes , err  =  p .Receive (1 )
387+ 		receiveBytes , _ ,  err  =  p .Receive (1 )
380388		if  err  !=  nil  {
381389			log .Errorf ("Failed to receive byte for v1 prefix " + 
382390				"check: %v" , err )
@@ -473,11 +481,11 @@ func createV1Prefix(net wire.BitcoinNet) []byte {
473481// CompleteHandshake finishes the v2 protocol negotiation and optionally sends 
474482// decoy packets after sending the garbage terminator. 
475483func  (p  * Peer ) CompleteHandshake (initiating  bool , decoyContentLens  []int ,
476- 	net  wire.BitcoinNet ) error  {
484+ 	btcnet  wire.BitcoinNet ) error  {
477485
478486	log .Debugf ("Completing v2 handshake (initiating=%v, " + 
479487		"num_decoys=%d, net=%v)" , initiating , len (decoyContentLens ),
480- 		net )
488+ 		btcnet )
481489
482490	var  receivedPrefix  []byte 
483491	if  initiating  {
@@ -498,8 +506,28 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
498506			len (receivedPrefix ), 64 - len (receivedPrefix ))
499507	}
500508
501- 	recvData , err  :=  p .Receive (64  -  len (receivedPrefix ))
509+ 	recvData , numRead ,  err  :=  p .Receive (64  -  len (receivedPrefix ))
502510	if  err  !=  nil  {
511+ 		// If we receive an error when reading off the wire and we read 
512+ 		// zero bytes, then we will reconnect to the peer using v1. 
513+ 		// There are several different errors that Receive can return 
514+ 		// that indicate we should reconnect. Instead of special-casing 
515+ 		// them all, just perform these checks if any error was 
516+ 		// returned. 
517+ 		if  numRead  ==  0  &&  initiating  {
518+ 			// The peer most likely attempted to parse our 64-byte 
519+ 			// elligator-swift key as a version message and failed 
520+ 			// when trying to parse the message header into 
521+ 			// something valid. In this case, return a special 
522+ 			// error that signals to the server that we can 
523+ 			// reconnect with the OG v1 scheme. 
524+ 			log .Debugf ("Received transport error during "  + 
525+ 				"v2 handshake, retying downgraded v1 "  + 
526+ 				"connection." )
527+ 			return  ErrShouldDowngradeToV1 
528+ 		}
529+ 
530+ 		// If we are the recipient, we can fail. 
503531		log .Errorf ("Failed to receive peer's ellswift key data: %v" ,
504532			err )
505533		return  err 
@@ -533,7 +561,7 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
533561
534562	// Calculate the v1 protocol's message prefix and see if the bytes read 
535563	// read into ellswiftTheirs matches it. 
536- 	v1Prefix  :=  createV1Prefix (net )
564+ 	v1Prefix  :=  createV1Prefix (btcnet )
537565
538566	// ellswiftTheirs should be at least 16 bytes if receive succeeded, but 
539567	// just in case, check the size. 
@@ -546,7 +574,7 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
546574
547575	if  ! initiating  &&  bytes .Equal (ellswiftTheirs [4 :16 ], v1Prefix [4 :16 ]) {
548576		log .Warnf ("Peer sent v1 version message for wrong network " + 
549- 			"(expected %v)" , net )
577+ 			"(expected %v)" , btcnet )
550578		return  errWrongNetV1Peer 
551579	}
552580
@@ -563,7 +591,7 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
563591
564592	log .Tracef ("Calculated ECDH shared secret: %x" , ecdhSecret )
565593
566- 	err  =  p .createV2Ciphers (ecdhSecret [:], initiating , net )
594+ 	err  =  p .createV2Ciphers (ecdhSecret [:], initiating , btcnet )
567595	if  err  !=  nil  {
568596		// createV2Ciphers logs its own errors 
569597		return  err 
@@ -606,7 +634,7 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
606634		p .recvGarbageTerm )
607635
608636	// Skip garbage until encountering garbage terminator. 
609- 	recvGarbage , err  :=  p .Receive (16 )
637+ 	recvGarbage , _ ,  err  :=  p .Receive (16 )
610638	if  err  !=  nil  {
611639		log .Errorf ("Failed to receive initial 16 bytes of " + 
612640			"garbage: %v" , err )
@@ -645,7 +673,7 @@ func (p *Peer) CompleteHandshake(initiating bool, decoyContentLens []int,
645673		log .Tracef ("Garbage terminator not found, receiving 1 more " + 
646674			"byte (total_received=%d)" , recvGarbageLen )
647675
648- 		recvData , err  :=  p .Receive (1 )
676+ 		recvData , _ ,  err  :=  p .Receive (1 )
649677		if  err  !=  nil  {
650678			log .Errorf ("Failed to receive garbage " + 
651679				"byte %d: %v" , recvGarbageLen + 1 , err )
@@ -746,7 +774,7 @@ func (p *Peer) V2ReceivePacket(aad []byte) ([]byte, error) {
746774			lengthFieldLen )
747775
748776		// Decrypt the length field so we know how many more bytes to receive. 
749- 		encContentsLen , err  :=  p .Receive (lengthFieldLen )
777+ 		encContentsLen , _ ,  err  :=  p .Receive (lengthFieldLen )
750778		if  err  !=  nil  {
751779			log .Errorf ("Failed to receive encrypted length: %v" ,
752780				err )
@@ -783,7 +811,7 @@ func (p *Peer) V2ReceivePacket(aad []byte) ([]byte, error) {
783811		log .Tracef ("Receiving %d bytes for encrypted packet body" ,
784812			numBytes )
785813
786- 		aeadCiphertext , err  :=  p .Receive (numBytes )
814+ 		aeadCiphertext , _ ,  err  :=  p .Receive (numBytes )
787815		if  err  !=  nil  {
788816			log .Errorf ("Failed to receive encrypted " + 
789817				"packet body: %v" , err )
@@ -844,7 +872,7 @@ func (p *Peer) Send(data []byte) (int, error) {
844872}
845873
846874// Receive receives numBytes bytes from the underlying connection. 
847- func  (p  * Peer ) Receive (numBytes  int ) ([]byte , error ) {
875+ func  (p  * Peer ) Receive (numBytes  int ) ([]byte , int ,  error ) {
848876	b  :=  make ([]byte , numBytes )
849877	index  :=  0 
850878	total  :=  0 
@@ -858,12 +886,12 @@ func (p *Peer) Receive(numBytes int) ([]byte, error) {
858886			// used implicitly by the loop structure. 
859887			log .Criticalf ("Receive logic error: total=%d > " + 
860888				"numBytes=%d" , total , numBytes )
861- 			return  nil , errFailedToRecv 
889+ 			return  nil , total ,  errFailedToRecv 
862890		}
863891
864892		if  total  ==  numBytes  {
865893			log .Tracef ("Successfully received %d bytes" , total )
866- 			return  b , nil 
894+ 			return  b , total ,  nil 
867895		}
868896
869897		log .Tracef ("Calling Read (need %d bytes, have " + 
@@ -873,7 +901,7 @@ func (p *Peer) Receive(numBytes int) ([]byte, error) {
873901		if  err  !=  nil  {
874902			log .Errorf ("Receive failed after reading %d bytes " + 
875903				"(target %d): %v" , total + n , numBytes , err )
876- 			return  nil , err 
904+ 			return  nil , total ,  err 
877905		}
878906
879907		log .Tracef ("Read returned %d bytes" , n )
0 commit comments