ceremonyclient/go-libp2p/p2p/net/mock/mock_conn.go

188 lines
3.6 KiB
Go
Raw Normal View History

2023-08-21 03:50:38 +00:00
package mocknet
import (
"container/list"
"context"
"strconv"
"sync"
"sync/atomic"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)
var connCounter atomic.Int64
// conn represents one side's perspective of a
// live connection between two peers.
// it goes over a particular link.
type conn struct {
notifLk sync.Mutex
id int64
local peer.ID
remote peer.ID
localAddr ma.Multiaddr
remoteAddr ma.Multiaddr
localPrivKey ic.PrivKey
remotePubKey ic.PubKey
net *peernet
link *link
rconn *conn // counterpart
streams list.List
stat network.ConnStats
closeOnce sync.Once
isClosed atomic.Bool
sync.RWMutex
}
func newConn(ln, rn *peernet, l *link, dir network.Direction) *conn {
c := &conn{net: ln, link: l}
c.local = ln.peer
c.remote = rn.peer
c.stat.Direction = dir
c.id = connCounter.Add(1)
c.localAddr = ln.ps.Addrs(ln.peer)[0]
for _, a := range rn.ps.Addrs(rn.peer) {
if !manet.IsIPUnspecified(a) {
c.remoteAddr = a
break
}
}
if c.remoteAddr == nil {
c.remoteAddr = rn.ps.Addrs(rn.peer)[0]
}
c.localPrivKey = ln.ps.PrivKey(ln.peer)
c.remotePubKey = rn.ps.PubKey(rn.peer)
return c
}
func (c *conn) IsClosed() bool {
return c.isClosed.Load()
}
func (c *conn) ID() string {
return strconv.FormatInt(c.id, 10)
}
func (c *conn) Close() error {
c.closeOnce.Do(func() {
c.isClosed.Store(true)
go c.rconn.Close()
c.teardown()
})
return nil
}
func (c *conn) teardown() {
for _, s := range c.allStreams() {
s.Reset()
}
c.net.removeConn(c)
}
func (c *conn) addStream(s *stream) {
c.Lock()
defer c.Unlock()
s.conn = c
c.streams.PushBack(s)
}
func (c *conn) removeStream(s *stream) {
c.Lock()
defer c.Unlock()
for e := c.streams.Front(); e != nil; e = e.Next() {
if s == e.Value {
c.streams.Remove(e)
return
}
}
}
func (c *conn) allStreams() []network.Stream {
c.RLock()
defer c.RUnlock()
strs := make([]network.Stream, 0, c.streams.Len())
for e := c.streams.Front(); e != nil; e = e.Next() {
s := e.Value.(*stream)
strs = append(strs, s)
}
return strs
}
func (c *conn) remoteOpenedStream(s *stream) {
c.addStream(s)
c.net.handleNewStream(s)
}
func (c *conn) openStream() *stream {
sl, sr := newStreamPair()
go c.rconn.remoteOpenedStream(sr)
c.addStream(sl)
return sl
}
func (c *conn) NewStream(context.Context) (network.Stream, error) {
log.Debugf("Conn.NewStreamWithProtocol: %s --> %s", c.local, c.remote)
s := c.openStream()
return s, nil
}
func (c *conn) GetStreams() []network.Stream {
return c.allStreams()
}
// LocalMultiaddr is the Multiaddr on this side
func (c *conn) LocalMultiaddr() ma.Multiaddr {
return c.localAddr
}
// LocalPeer is the Peer on our side of the connection
func (c *conn) LocalPeer() peer.ID {
return c.local
}
// RemoteMultiaddr is the Multiaddr on the remote side
func (c *conn) RemoteMultiaddr() ma.Multiaddr {
return c.remoteAddr
}
// RemotePeer is the Peer on the remote side
func (c *conn) RemotePeer() peer.ID {
return c.remote
}
// RemotePublicKey is the private key of the peer on our side.
func (c *conn) RemotePublicKey() ic.PubKey {
return c.remotePubKey
}
// ConnState of security connection. Empty if not supported.
func (c *conn) ConnState() network.ConnectionState {
return network.ConnectionState{}
}
// Stat returns metadata about the connection
func (c *conn) Stat() network.ConnStats {
return c.stat
}
func (c *conn) Scope() network.ConnScope {
return &network.NullScope{}
}