// Copyright 2014 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . package p2p import ( "fmt" "strings" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" ) // Protocol represents a P2P subprotocol implementation. type Protocol struct { // Name should contain the official protocol name, // often a three-letter word. Name string // Version should contain the version number of the protocol. Version uint // Length should contain the number of message codes used // by the protocol. Length uint64 // Run is called in a new goroutine when the protocol has been // negotiated with a peer. It should read and write messages from // rw. The Payload for each message must be fully consumed. // // The peer connection is closed when Start returns. It should return // any protocol-level error (such as an I/O error) that is // encountered. Run func(peer *Peer, rw MsgReadWriter) error // NodeInfo is an optional helper method to retrieve protocol specific metadata // about the host node. NodeInfo func() interface{} // PeerInfo is an optional helper method to retrieve protocol specific metadata // about a certain peer in the network. If an info retrieval function is set, // but returns nil, it is assumed that the protocol handshake is still running. PeerInfo func(id enode.ID) interface{} // DialCandidates, if non-nil, is a way to tell Server about protocol-specific nodes // that should be dialed. The server continuously reads nodes from the iterator and // attempts to create connections to them. DialCandidates enode.Iterator // Attributes contains protocol specific information for the node record. Attributes []enr.Entry } func (p Protocol) cap() Cap { return Cap{p.Name, p.Version} } // Cap is the structure of a peer capability. type Cap struct { Name string Version uint } func (cap Cap) String() string { return fmt.Sprintf("%s/%d", cap.Name, cap.Version) } // Cmp defines the canonical sorting order of capabilities. func (cap Cap) Cmp(other Cap) int { if cap.Name == other.Name { if cap.Version < other.Version { return -1 } if cap.Version > other.Version { return 1 } return 0 } return strings.Compare(cap.Name, other.Name) }