github.com/ethereum/go-ethereum@v1.16.1/p2p/peer_error.go (about)

     1  // Copyright 2014 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 p2p
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  )
    23  
    24  const (
    25  	errInvalidMsgCode = iota
    26  	errInvalidMsg
    27  )
    28  
    29  var errorToString = map[int]string{
    30  	errInvalidMsgCode: "invalid message code",
    31  	errInvalidMsg:     "invalid message",
    32  }
    33  
    34  type peerError struct {
    35  	code    int
    36  	message string
    37  }
    38  
    39  func newPeerError(code int, format string, v ...interface{}) *peerError {
    40  	desc, ok := errorToString[code]
    41  	if !ok {
    42  		panic("invalid error code")
    43  	}
    44  	err := &peerError{code, desc}
    45  	if format != "" {
    46  		err.message += ": " + fmt.Sprintf(format, v...)
    47  	}
    48  	return err
    49  }
    50  
    51  func (pe *peerError) Error() string {
    52  	return pe.message
    53  }
    54  
    55  var errProtocolReturned = errors.New("protocol returned")
    56  
    57  type DiscReason uint8
    58  
    59  const (
    60  	DiscRequested DiscReason = iota
    61  	DiscNetworkError
    62  	DiscProtocolError
    63  	DiscUselessPeer
    64  	DiscTooManyPeers
    65  	DiscAlreadyConnected
    66  	DiscIncompatibleVersion
    67  	DiscInvalidIdentity
    68  	DiscQuitting
    69  	DiscUnexpectedIdentity
    70  	DiscSelf
    71  	DiscReadTimeout
    72  	DiscSubprotocolError = DiscReason(0x10)
    73  
    74  	DiscInvalid = 0xff
    75  )
    76  
    77  var discReasonToString = [...]string{
    78  	DiscRequested:           "disconnect requested",
    79  	DiscNetworkError:        "network error",
    80  	DiscProtocolError:       "breach of protocol",
    81  	DiscUselessPeer:         "useless peer",
    82  	DiscTooManyPeers:        "too many peers",
    83  	DiscAlreadyConnected:    "already connected",
    84  	DiscIncompatibleVersion: "incompatible p2p protocol version",
    85  	DiscInvalidIdentity:     "invalid node identity",
    86  	DiscQuitting:            "client quitting",
    87  	DiscUnexpectedIdentity:  "unexpected identity",
    88  	DiscSelf:                "connected to self",
    89  	DiscReadTimeout:         "read timeout",
    90  	DiscSubprotocolError:    "subprotocol error",
    91  	DiscInvalid:             "invalid disconnect reason",
    92  }
    93  
    94  func (d DiscReason) String() string {
    95  	if len(discReasonToString) <= int(d) || discReasonToString[d] == "" {
    96  		return fmt.Sprintf("unknown disconnect reason %d", d)
    97  	}
    98  	return discReasonToString[d]
    99  }
   100  
   101  func (d DiscReason) Error() string {
   102  	return d.String()
   103  }
   104  
   105  func discReasonForError(err error) DiscReason {
   106  	if reason, ok := err.(DiscReason); ok {
   107  		return reason
   108  	}
   109  	if errors.Is(err, errProtocolReturned) {
   110  		return DiscQuitting
   111  	}
   112  	peerError, ok := err.(*peerError)
   113  	if ok {
   114  		switch peerError.code {
   115  		case errInvalidMsgCode, errInvalidMsg:
   116  			return DiscProtocolError
   117  		default:
   118  			return DiscSubprotocolError
   119  		}
   120  	}
   121  	return DiscSubprotocolError
   122  }