github.com/dominant-strategies/go-quai@v0.28.2/p2p/discover/v5wire/msg.go (about)

     1  // Copyright 2019 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 v5wire
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  
    23  	"github.com/dominant-strategies/go-quai/common/mclock"
    24  	"github.com/dominant-strategies/go-quai/p2p/enode"
    25  	"github.com/dominant-strategies/go-quai/p2p/enr"
    26  	"github.com/dominant-strategies/go-quai/rlp"
    27  )
    28  
    29  // Packet is implemented by all message types.
    30  type Packet interface {
    31  	Name() string        // Name returns a string corresponding to the message type.
    32  	Kind() byte          // Kind returns the message type.
    33  	RequestID() []byte   // Returns the request ID.
    34  	SetRequestID([]byte) // Sets the request ID.
    35  }
    36  
    37  // Message types.
    38  const (
    39  	PingMsg byte = iota + 1
    40  	PongMsg
    41  	FindnodeMsg
    42  	NodesMsg
    43  	TalkRequestMsg
    44  	TalkResponseMsg
    45  	RequestTicketMsg
    46  	TicketMsg
    47  	RegtopicMsg
    48  	RegconfirmationMsg
    49  	TopicQueryMsg
    50  
    51  	UnknownPacket   = byte(255) // any non-decryptable packet
    52  	WhoareyouPacket = byte(254) // the WHOAREYOU packet
    53  )
    54  
    55  // Protocol messages.
    56  type (
    57  	// Unknown represents any packet that can't be decrypted.
    58  	Unknown struct {
    59  		Nonce Nonce
    60  	}
    61  
    62  	// WHOAREYOU contains the handshake challenge.
    63  	Whoareyou struct {
    64  		ChallengeData []byte   // Encoded challenge
    65  		Nonce         Nonce    // Nonce of request packet
    66  		IDNonce       [16]byte // Identity proof data
    67  		RecordSeq     uint64   // ENR sequence number of recipient
    68  
    69  		// Node is the locally known node record of recipient.
    70  		// This must be set by the caller of Encode.
    71  		Node *enode.Node
    72  
    73  		sent mclock.AbsTime // for handshake GC.
    74  	}
    75  
    76  	// PING is sent during liveness checks.
    77  	Ping struct {
    78  		ReqID  []byte
    79  		ENRSeq uint64
    80  	}
    81  
    82  	// PONG is the reply to PING.
    83  	Pong struct {
    84  		ReqID  []byte
    85  		ENRSeq uint64
    86  		ToIP   net.IP // These fields should mirror the UDP envelope address of the ping
    87  		ToPort uint16 // packet, which provides a way to discover the the external address (after NAT).
    88  	}
    89  
    90  	// FINDNODE is a query for nodes in the given bucket.
    91  	Findnode struct {
    92  		ReqID     []byte
    93  		Distances []uint
    94  	}
    95  
    96  	// NODES is the reply to FINDNODE and TOPICQUERY.
    97  	Nodes struct {
    98  		ReqID []byte
    99  		Total uint8
   100  		Nodes []*enr.Record
   101  	}
   102  
   103  	// TALKREQ is an application-level request.
   104  	TalkRequest struct {
   105  		ReqID    []byte
   106  		Protocol string
   107  		Message  []byte
   108  	}
   109  
   110  	// TALKRESP is the reply to TALKREQ.
   111  	TalkResponse struct {
   112  		ReqID   []byte
   113  		Message []byte
   114  	}
   115  
   116  	// REQUESTTICKET requests a ticket for a topic queue.
   117  	RequestTicket struct {
   118  		ReqID []byte
   119  		Topic []byte
   120  	}
   121  
   122  	// TICKET is the response to REQUESTTICKET.
   123  	Ticket struct {
   124  		ReqID  []byte
   125  		Ticket []byte
   126  	}
   127  
   128  	// REGTOPIC registers the sender in a topic queue using a ticket.
   129  	Regtopic struct {
   130  		ReqID  []byte
   131  		Ticket []byte
   132  		ENR    *enr.Record
   133  	}
   134  
   135  	// REGCONFIRMATION is the reply to REGTOPIC.
   136  	Regconfirmation struct {
   137  		ReqID      []byte
   138  		Registered bool
   139  	}
   140  
   141  	// TOPICQUERY asks for nodes with the given topic.
   142  	TopicQuery struct {
   143  		ReqID []byte
   144  		Topic []byte
   145  	}
   146  )
   147  
   148  // DecodeMessage decodes the message body of a packet.
   149  func DecodeMessage(ptype byte, body []byte) (Packet, error) {
   150  	var dec Packet
   151  	switch ptype {
   152  	case PingMsg:
   153  		dec = new(Ping)
   154  	case PongMsg:
   155  		dec = new(Pong)
   156  	case FindnodeMsg:
   157  		dec = new(Findnode)
   158  	case NodesMsg:
   159  		dec = new(Nodes)
   160  	case TalkRequestMsg:
   161  		dec = new(TalkRequest)
   162  	case TalkResponseMsg:
   163  		dec = new(TalkResponse)
   164  	case RequestTicketMsg:
   165  		dec = new(RequestTicket)
   166  	case TicketMsg:
   167  		dec = new(Ticket)
   168  	case RegtopicMsg:
   169  		dec = new(Regtopic)
   170  	case RegconfirmationMsg:
   171  		dec = new(Regconfirmation)
   172  	case TopicQueryMsg:
   173  		dec = new(TopicQuery)
   174  	default:
   175  		return nil, fmt.Errorf("unknown packet type %d", ptype)
   176  	}
   177  	if err := rlp.DecodeBytes(body, dec); err != nil {
   178  		return nil, err
   179  	}
   180  	if dec.RequestID() != nil && len(dec.RequestID()) > 8 {
   181  		return nil, ErrInvalidReqID
   182  	}
   183  	return dec, nil
   184  }
   185  
   186  func (*Whoareyou) Name() string        { return "WHOAREYOU/v5" }
   187  func (*Whoareyou) Kind() byte          { return WhoareyouPacket }
   188  func (*Whoareyou) RequestID() []byte   { return nil }
   189  func (*Whoareyou) SetRequestID([]byte) {}
   190  
   191  func (*Unknown) Name() string        { return "UNKNOWN/v5" }
   192  func (*Unknown) Kind() byte          { return UnknownPacket }
   193  func (*Unknown) RequestID() []byte   { return nil }
   194  func (*Unknown) SetRequestID([]byte) {}
   195  
   196  func (*Ping) Name() string             { return "PING/v5" }
   197  func (*Ping) Kind() byte               { return PingMsg }
   198  func (p *Ping) RequestID() []byte      { return p.ReqID }
   199  func (p *Ping) SetRequestID(id []byte) { p.ReqID = id }
   200  
   201  func (*Pong) Name() string             { return "PONG/v5" }
   202  func (*Pong) Kind() byte               { return PongMsg }
   203  func (p *Pong) RequestID() []byte      { return p.ReqID }
   204  func (p *Pong) SetRequestID(id []byte) { p.ReqID = id }
   205  
   206  func (*Findnode) Name() string             { return "FINDNODE/v5" }
   207  func (*Findnode) Kind() byte               { return FindnodeMsg }
   208  func (p *Findnode) RequestID() []byte      { return p.ReqID }
   209  func (p *Findnode) SetRequestID(id []byte) { p.ReqID = id }
   210  
   211  func (*Nodes) Name() string             { return "NODES/v5" }
   212  func (*Nodes) Kind() byte               { return NodesMsg }
   213  func (p *Nodes) RequestID() []byte      { return p.ReqID }
   214  func (p *Nodes) SetRequestID(id []byte) { p.ReqID = id }
   215  
   216  func (*TalkRequest) Name() string             { return "TALKREQ/v5" }
   217  func (*TalkRequest) Kind() byte               { return TalkRequestMsg }
   218  func (p *TalkRequest) RequestID() []byte      { return p.ReqID }
   219  func (p *TalkRequest) SetRequestID(id []byte) { p.ReqID = id }
   220  
   221  func (*TalkResponse) Name() string             { return "TALKRESP/v5" }
   222  func (*TalkResponse) Kind() byte               { return TalkResponseMsg }
   223  func (p *TalkResponse) RequestID() []byte      { return p.ReqID }
   224  func (p *TalkResponse) SetRequestID(id []byte) { p.ReqID = id }
   225  
   226  func (*RequestTicket) Name() string             { return "REQTICKET/v5" }
   227  func (*RequestTicket) Kind() byte               { return RequestTicketMsg }
   228  func (p *RequestTicket) RequestID() []byte      { return p.ReqID }
   229  func (p *RequestTicket) SetRequestID(id []byte) { p.ReqID = id }
   230  
   231  func (*Regtopic) Name() string             { return "REGTOPIC/v5" }
   232  func (*Regtopic) Kind() byte               { return RegtopicMsg }
   233  func (p *Regtopic) RequestID() []byte      { return p.ReqID }
   234  func (p *Regtopic) SetRequestID(id []byte) { p.ReqID = id }
   235  
   236  func (*Ticket) Name() string             { return "TICKET/v5" }
   237  func (*Ticket) Kind() byte               { return TicketMsg }
   238  func (p *Ticket) RequestID() []byte      { return p.ReqID }
   239  func (p *Ticket) SetRequestID(id []byte) { p.ReqID = id }
   240  
   241  func (*Regconfirmation) Name() string             { return "REGCONFIRMATION/v5" }
   242  func (*Regconfirmation) Kind() byte               { return RegconfirmationMsg }
   243  func (p *Regconfirmation) RequestID() []byte      { return p.ReqID }
   244  func (p *Regconfirmation) SetRequestID(id []byte) { p.ReqID = id }
   245  
   246  func (*TopicQuery) Name() string             { return "TOPICQUERY/v5" }
   247  func (*TopicQuery) Kind() byte               { return TopicQueryMsg }
   248  func (p *TopicQuery) RequestID() []byte      { return p.ReqID }
   249  func (p *TopicQuery) SetRequestID(id []byte) { p.ReqID = id }