github.com/phillinzzz/newBsc@v1.1.6/eth/protocols/diff/handshake.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package diff
    18  
    19  import (
    20  	"fmt"
    21  	"time"
    22  
    23  	"github.com/phillinzzz/newBsc/common/gopool"
    24  	"github.com/phillinzzz/newBsc/p2p"
    25  )
    26  
    27  const (
    28  	// handshakeTimeout is the maximum allowed time for the `diff` handshake to
    29  	// complete before dropping the connection.= as malicious.
    30  	handshakeTimeout = 5 * time.Second
    31  )
    32  
    33  // Handshake executes the diff protocol handshake,
    34  func (p *Peer) Handshake(diffSync bool) error {
    35  	// Send out own handshake in a new thread
    36  	errc := make(chan error, 2)
    37  
    38  	var cap DiffCapPacket // safe to read after two values have been received from errc
    39  
    40  	gopool.Submit(func() {
    41  		errc <- p2p.Send(p.rw, DiffCapMsg, &DiffCapPacket{
    42  			DiffSync: diffSync,
    43  			Extra:    defaultExtra,
    44  		})
    45  	})
    46  	gopool.Submit(func() {
    47  		errc <- p.readCap(&cap)
    48  	})
    49  	timeout := time.NewTimer(handshakeTimeout)
    50  	defer timeout.Stop()
    51  	for i := 0; i < 2; i++ {
    52  		select {
    53  		case err := <-errc:
    54  			if err != nil {
    55  				return err
    56  			}
    57  		case <-timeout.C:
    58  			return p2p.DiscReadTimeout
    59  		}
    60  	}
    61  	p.diffSync = cap.DiffSync
    62  	return nil
    63  }
    64  
    65  // readStatus reads the remote handshake message.
    66  func (p *Peer) readCap(cap *DiffCapPacket) error {
    67  	msg, err := p.rw.ReadMsg()
    68  	if err != nil {
    69  		return err
    70  	}
    71  	if msg.Code != DiffCapMsg {
    72  		return fmt.Errorf("%w: first msg has code %x (!= %x)", errNoCapMsg, msg.Code, DiffCapMsg)
    73  	}
    74  	if msg.Size > maxMessageSize {
    75  		return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize)
    76  	}
    77  	// Decode the handshake and make sure everything matches
    78  	if err := msg.Decode(cap); err != nil {
    79  		return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
    80  	}
    81  	return nil
    82  }