Browse Source

新增握手处理器

skyfffire 2 years ago
parent
commit
76795c6199
4 changed files with 143 additions and 11 deletions
  1. 5 1
      cmd/p2p/main.go
  2. 9 8
      p2p/peer.go
  3. 119 0
      p2p/peer_error.go
  4. 10 2
      p2p/server.go

+ 5 - 1
cmd/p2p/main.go

@@ -7,8 +7,12 @@ import (
 
 func main() {
 	key, _ := crypto.GenerateKey()
+	config := p2p.Config{
+		PrivateKey: key,
+		Name:       "p2p",
+	}
 	server := &p2p.Server{
-		Config: p2p.Config{PrivateKey: key},
+		Config: config,
 	}
 
 	err := server.Start()

+ 9 - 8
p2p/peer.go

@@ -1,6 +1,7 @@
 package p2p
 
 import (
+	"blockchain-go/p2p/enode"
 	"errors"
 	"time"
 )
@@ -62,14 +63,14 @@ const (
 // PeerEvent is an event emitted when peers are either added or dropped from
 // a p2p.Server or when a message is sent or received on a peer connection
 type PeerEvent struct {
-	Type PeerEventType `json:"type"`
-	//Peer          enode.ID      `json:"peer"`
-	Error         string  `json:"error,omitempty"`
-	Protocol      string  `json:"protocol,omitempty"`
-	MsgCode       *uint64 `json:"msg_code,omitempty"`
-	MsgSize       *uint32 `json:"msg_size,omitempty"`
-	LocalAddress  string  `json:"local,omitempty"`
-	RemoteAddress string  `json:"remote,omitempty"`
+	Type          PeerEventType `json:"type"`
+	Peer          enode.ID      `json:"peer"`
+	Error         string        `json:"error,omitempty"`
+	Protocol      string        `json:"protocol,omitempty"`
+	MsgCode       *uint64       `json:"msg_code,omitempty"`
+	MsgSize       *uint32       `json:"msg_size,omitempty"`
+	LocalAddress  string        `json:"local,omitempty"`
+	RemoteAddress string        `json:"remote,omitempty"`
 }
 
 // Peer represents a connected remote node.

+ 119 - 0
p2p/peer_error.go

@@ -0,0 +1,119 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+package p2p
+
+import (
+	"errors"
+	"fmt"
+)
+
+const (
+	errInvalidMsgCode = iota
+	errInvalidMsg
+)
+
+var errorToString = map[int]string{
+	errInvalidMsgCode: "invalid message code",
+	errInvalidMsg:     "invalid message",
+}
+
+type peerError struct {
+	code    int
+	message string
+}
+
+func newPeerError(code int, format string, v ...interface{}) *peerError {
+	desc, ok := errorToString[code]
+	if !ok {
+		panic("invalid error code")
+	}
+	err := &peerError{code, desc}
+	if format != "" {
+		err.message += ": " + fmt.Sprintf(format, v...)
+	}
+	return err
+}
+
+func (pe *peerError) Error() string {
+	return pe.message
+}
+
+var errProtocolReturned = errors.New("protocol returned")
+
+type DiscReason uint8
+
+const (
+	DiscRequested DiscReason = iota
+	DiscNetworkError
+	DiscProtocolError
+	DiscUselessPeer
+	DiscTooManyPeers
+	DiscAlreadyConnected
+	DiscIncompatibleVersion
+	DiscInvalidIdentity
+	DiscQuitting
+	DiscUnexpectedIdentity
+	DiscSelf
+	DiscReadTimeout
+	DiscSubprotocolError = 0x10
+)
+
+var discReasonToString = [...]string{
+	DiscRequested:           "disconnect requested",
+	DiscNetworkError:        "network error",
+	DiscProtocolError:       "breach of protocol",
+	DiscUselessPeer:         "useless peer",
+	DiscTooManyPeers:        "too many peers",
+	DiscAlreadyConnected:    "already connected",
+	DiscIncompatibleVersion: "incompatible p2p protocol version",
+	DiscInvalidIdentity:     "invalid node identity",
+	DiscQuitting:            "client quitting",
+	DiscUnexpectedIdentity:  "unexpected identity",
+	DiscSelf:                "connected to self",
+	DiscReadTimeout:         "read timeout",
+	DiscSubprotocolError:    "subprotocol error",
+}
+
+func (d DiscReason) String() string {
+	if len(discReasonToString) < int(d) {
+		return fmt.Sprintf("unknown disconnect reason %d", d)
+	}
+	return discReasonToString[d]
+}
+
+func (d DiscReason) Error() string {
+	return d.String()
+}
+
+func discReasonForError(err error) DiscReason {
+	if reason, ok := err.(DiscReason); ok {
+		return reason
+	}
+	if err == errProtocolReturned {
+		return DiscQuitting
+	}
+	peerError, ok := err.(*peerError)
+	if ok {
+		switch peerError.code {
+		case errInvalidMsgCode, errInvalidMsg:
+			return DiscProtocolError
+		default:
+			return DiscSubprotocolError
+		}
+	}
+	return DiscSubprotocolError
+}

+ 10 - 2
p2p/server.go

@@ -26,7 +26,7 @@ type Server struct {
 	running bool
 
 	//listener net.Listener
-	//ourHandshake *protoHandshake
+	ourHandshake *protoHandshake
 	//loopWG sync.WaitGroup // loop, listenLoop
 	//peerFeed event.Feed
 	//log log.Logger
@@ -59,7 +59,15 @@ func (srv *Server) Start() (err error) {
 }
 
 func (srv *Server) setupLocalNode() (err error) {
-	_ = crypto.FromECDSAPub(&srv.PrivateKey.PublicKey)
+	publicKey := crypto.FromECDSAPub(&srv.PrivateKey.PublicKey)
+	// 新增握手处理器
+	srv.ourHandshake = &protoHandshake{
+		Version: baseProtocolVersion,
+		Name:    srv.Name,
+		ID:      publicKey[1:],
+	}
+
+	// TODO 新增协议,欺骗对等节点,先尝试没有协议的版本
 
 	return nil
 }