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