github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/vntp2p/peer.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt 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-vnt 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-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vntp2p
    18  
    19  import (
    20  	// "crypto/ecdsa"
    21  	// "crypto/elliptic"
    22  	"bufio"
    23  	"crypto/ecdsa"
    24  	"encoding/json"
    25  	"net"
    26  	"sync"
    27  	"sync/atomic"
    28  
    29  	inet "github.com/libp2p/go-libp2p-net"
    30  	libp2p "github.com/libp2p/go-libp2p-peer"
    31  	ma "github.com/multiformats/go-multiaddr"
    32  	manet "github.com/multiformats/go-multiaddr-net"
    33  	"github.com/vntchain/go-vnt/event"
    34  	"github.com/vntchain/go-vnt/log"
    35  )
    36  
    37  type PeerEventType string
    38  
    39  const (
    40  	// PeerEventTypeAdd is the type of event emitted when a peer is added
    41  	// to a p2p.Server
    42  	PeerEventTypeAdd PeerEventType = "add"
    43  
    44  	// PeerEventTypeDrop is the type of event emitted when a peer is
    45  	// dropped from a p2p.Server
    46  	PeerEventTypeDrop PeerEventType = "drop"
    47  
    48  	// PeerEventTypeMsgSend is the type of event emitted when a
    49  	// message is successfully sent to a peer
    50  	PeerEventTypeMsgSend PeerEventType = "msgsend"
    51  
    52  	// PeerEventTypeMsgRecv is the type of event emitted when a
    53  	// message is received from a peer
    54  	PeerEventTypeMsgRecv PeerEventType = "msgrecv"
    55  )
    56  
    57  // PeerEvent is an event emitted when peers are either added or dropped from
    58  // a p2p.Server or when a message is sent or received on a peer connection
    59  type PeerEvent struct {
    60  	Type     PeerEventType `json:"type"`
    61  	Peer     libp2p.ID     `json:"peer"`
    62  	Error    string        `json:"error,omitempty"`
    63  	Protocol string        `json:"protocol,omitempty"`
    64  	MsgCode  *uint64       `json:"msg_code,omitempty"`
    65  	MsgSize  *uint32       `json:"msg_size,omitempty"`
    66  }
    67  
    68  type PeerInfo struct {
    69  	ID      string   `json:"id"`   // Unique node identifier (also the encryption key)
    70  	Name    string   `json:"name"` // Name of the node, including client type, version, OS, custom data
    71  	Caps    []string `json:"caps"` // Sum-protocols advertised by this particular peer
    72  	Network struct {
    73  		LocalAddress  string `json:"localAddress"`  // Local endpoint of the TCP data connection
    74  		RemoteAddress string `json:"remoteAddress"` // Remote endpoint of the TCP data connection
    75  		Inbound       bool   `json:"inbound"`
    76  		Trusted       bool   `json:"trusted"`
    77  		Static        bool   `json:"static"`
    78  	} `json:"network"`
    79  	Protocols map[string]interface{} `json:"protocols"` // Sub-protocol specific metadata fields
    80  }
    81  
    82  type Peer struct {
    83  	rw      inet.Stream // libp2p stream
    84  	reseted int32       // Whether stream reseted
    85  	log     log.Logger
    86  	events  *event.Feed
    87  	err     chan error
    88  	msgers  map[string]*VNTMsger // protocolName - vntMessenger
    89  	server  *Server
    90  	wg      sync.WaitGroup
    91  }
    92  
    93  func newPeer(s *Stream, server *Server) *Peer {
    94  	m := make(map[string]*VNTMsger)
    95  	for i := range s.Protocols {
    96  		proto := s.Protocols[i]
    97  		vntMessenger := &VNTMsger{
    98  			protocol: proto,
    99  			in:       make(chan Msg),
   100  			err:      make(chan error, 100),
   101  			w:        s.stream,
   102  		}
   103  		m[proto.Name] = vntMessenger
   104  	}
   105  
   106  	p := &Peer{
   107  		rw:      s.stream,
   108  		log:     log.New("peer", s.stream.Conn().RemotePeer().ToString()),
   109  		err:     make(chan error),
   110  		reseted: 0,
   111  		msgers:  m,
   112  		server:  server,
   113  	}
   114  	for _, msger := range p.msgers {
   115  		msger.peer = p
   116  	}
   117  
   118  	return p
   119  }
   120  
   121  // Drop this peer forever because of protocol mismatch
   122  func (p *Peer) Drop() {
   123  	log.Trace("Drop peer forever", "pid", p.RemoteID())
   124  	p.rw.Conn().Close()
   125  	blacklist.write(p.RemoteID())
   126  }
   127  
   128  // LocalID return local PeerID for upper application
   129  func (p *Peer) LocalID() libp2p.ID {
   130  	return p.rw.Conn().LocalPeer()
   131  }
   132  
   133  // RemoteID return remote PeerID for upper application
   134  func (p *Peer) RemoteID() libp2p.ID {
   135  	return p.rw.Conn().RemotePeer()
   136  }
   137  
   138  func (p *Peer) Log() log.Logger {
   139  	return p.log
   140  }
   141  
   142  func (p *Peer) LocalAddr() net.Addr {
   143  	lma := p.rw.Conn().LocalMultiaddr()
   144  	return parseMultiaddr(lma)
   145  }
   146  
   147  func (p *Peer) RemoteAddr() net.Addr {
   148  	rma := p.rw.Conn().RemoteMultiaddr()
   149  	return parseMultiaddr(rma)
   150  }
   151  
   152  func parseMultiaddr(maddr ma.Multiaddr) net.Addr {
   153  	network, host, err := manet.DialArgs(maddr)
   154  	if err != nil {
   155  		log.Error("parseMultiaddr()", "dialArgs error", err)
   156  		return nil
   157  	}
   158  
   159  	switch network {
   160  	case "tcp", "tcp4", "tcp6":
   161  		na, err := net.ResolveTCPAddr(network, host)
   162  		if err != nil {
   163  			log.Error("parseMultiaddr()", "resolveTCPAddr error", err)
   164  			return nil
   165  		}
   166  		return na
   167  	case "udp", "udp4", "udp6":
   168  		na, err := net.ResolveUDPAddr(network, host)
   169  		if err != nil {
   170  			log.Error("parseMultiaddr()", "ResolveUDPAddr error", err)
   171  			return nil
   172  		}
   173  		return na
   174  	case "ip", "ip4", "ip6":
   175  		na, err := net.ResolveIPAddr(network, host)
   176  		if err != nil {
   177  			log.Error("parseMultiaddr()", "ResolveIPAddr error", err)
   178  			return nil
   179  		}
   180  		return na
   181  	}
   182  	log.Error("parseMultiaddr()", "network not supported", network)
   183  	return nil
   184  }
   185  
   186  func (p *Peer) Disconnect(reason DiscReason) {
   187  	// test for it
   188  	// p.rw.Conn().Close()
   189  	// p.rw.Close()
   190  
   191  	p.log.Debug("Disconnect", "reason", reason)
   192  	p.Reset()
   193  }
   194  
   195  // Reset Close both direction. Use this to tell the remote side to hang up and go away.
   196  // But only reset once.
   197  func (p *Peer) Reset() {
   198  	if !atomic.CompareAndSwapInt32(&p.reseted, 0, 1) {
   199  		return
   200  	}
   201  
   202  	if err := p.rw.Reset(); err != nil {
   203  		p.log.Debug("Reset peer connection", "error", err.Error())
   204  	} else {
   205  		p.log.Debug("Reset peer connection success")
   206  	}
   207  }
   208  
   209  func (p *Peer) Info() *PeerInfo {
   210  	info := &PeerInfo{
   211  		ID: p.RemoteID().String(),
   212  	}
   213  	info.Network.LocalAddress = p.rw.Conn().LocalMultiaddr().String()
   214  	info.Network.RemoteAddress = p.rw.Conn().RemoteMultiaddr().String()
   215  
   216  	// 此处暂时不处理状态
   217  	// info.Network.Static = p.rw.Conn().RemotePeer()
   218  	// info.Network.Trusted =
   219  	// info.Network.Inbound =
   220  
   221  	return info
   222  }
   223  
   224  func (p *Peer) run() (remoteRequested bool, err error) {
   225  	for _, msger := range p.msgers {
   226  		proto := msger.protocol
   227  		m := msger
   228  		p.wg.Add(1)
   229  		go func() {
   230  			err := proto.Run(p, m)
   231  			p.log.Debug("Run protocol error", "protocol", proto.Name, "error", err)
   232  
   233  			p.sendError(err)
   234  			p.wg.Done()
   235  		}()
   236  	}
   237  
   238  	err = <-p.err
   239  	remoteRequested = true
   240  	p.Reset()
   241  	p.log.Debug("P2P remote peer request close, but we need to wait for other protocol", "peer", p.RemoteID())
   242  	p.wg.Wait()
   243  	p.log.Debug("P2P wait complete!", "peer", p.RemoteID())
   244  
   245  	return remoteRequested, err
   246  }
   247  
   248  // sendError 为Peer的协议开了多个goroutine,可能多个协议都返回错误,
   249  // 退出只接收一次错误就可以,所以采用非阻塞发送错误
   250  func (p *Peer) sendError(err error) {
   251  	select {
   252  	case p.err <- err:
   253  	default:
   254  	}
   255  }
   256  
   257  type Stream struct {
   258  	stream    inet.Stream
   259  	Protocols []Protocol
   260  }
   261  
   262  //临时测试使用
   263  func WritePackage(rw *bufio.ReadWriter, code uint64, data []byte) ([]byte, error) {
   264  	//msg := &Msg{Code: code, Data: data, Size: uint32(len(data))}
   265  	msg := &Msg{}
   266  	// logg.Printf("Msg: %v", msg)
   267  	return json.Marshal(msg)
   268  }
   269  
   270  func PubkeyID(pub *ecdsa.PublicKey) libp2p.ID {
   271  	// var id NodeID
   272  	// pbytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
   273  	// if len(pbytes)-1 != len(id) {
   274  	// 	panic(fmt.Errorf("need %d bit pubkey, got %d bits", (len(id)+1)*8, len(pbytes)))
   275  	// }
   276  	// copy(id[:], pbytes[1:])
   277  	// return id
   278  	id, err := libp2p.IDFromPublicKey(pub)
   279  	if err != nil {
   280  		panic("wrong publick key")
   281  	}
   282  	return id
   283  }