mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-10 09:52:20 +08:00

I needed the network implementation in its own package, because I'll be writing several services that will plug into _it_ that shouldn't be part of the core net package. and then there were dependency conflicts. yay. mux + identify are good examples of what i mean.
126 lines
2.5 KiB
Go
126 lines
2.5 KiB
Go
package mocknet
|
|
|
|
import (
|
|
"container/list"
|
|
"sync"
|
|
|
|
ic "github.com/jbenet/go-ipfs/crypto"
|
|
inet "github.com/jbenet/go-ipfs/net"
|
|
mux "github.com/jbenet/go-ipfs/net/services/mux"
|
|
peer "github.com/jbenet/go-ipfs/peer"
|
|
|
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
|
)
|
|
|
|
// conn represents one side's perspective of a
|
|
// live connection between two peers.
|
|
// it goes over a particular link.
|
|
type conn struct {
|
|
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
|
|
|
|
sync.RWMutex
|
|
}
|
|
|
|
func (c *conn) Close() error {
|
|
for _, s := range c.allStreams() {
|
|
s.Close()
|
|
}
|
|
c.net.removeConn(c)
|
|
return nil
|
|
}
|
|
|
|
func (c *conn) addStream(s *stream) {
|
|
c.Lock()
|
|
s.conn = c
|
|
c.streams.PushBack(s)
|
|
c.Unlock()
|
|
}
|
|
|
|
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() []inet.Stream {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
|
|
strs := make([]inet.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 := c.link.newStreamPair()
|
|
c.addStream(sl)
|
|
c.rconn.remoteOpenedStream(sr)
|
|
return sl
|
|
}
|
|
|
|
func (c *conn) NewStreamWithProtocol(pr inet.ProtocolID) (inet.Stream, error) {
|
|
log.Debugf("Conn.NewStreamWithProtocol: %s --> %s", c.local, c.remote)
|
|
|
|
s := c.openStream()
|
|
if err := mux.WriteProtocolHeader(pr, s); err != nil {
|
|
s.Close()
|
|
return nil, err
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// LocalPrivateKey is the private key of the peer on our side.
|
|
func (c *conn) LocalPrivateKey() ic.PrivKey {
|
|
return c.localPrivKey
|
|
}
|
|
|
|
// 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
|
|
}
|