mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-29 18:05:18 +00:00
188 lines
3.6 KiB
Go
188 lines
3.6 KiB
Go
|
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{}
|
||
|
}
|