mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-24 20:07:45 +08:00
169 lines
4.3 KiB
Go
169 lines
4.3 KiB
Go
package conn
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"time"
|
|
|
|
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
|
msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
|
|
mpool "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
|
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
|
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
|
|
|
ic "github.com/jbenet/go-ipfs/p2p/crypto"
|
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
|
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
|
|
u "github.com/jbenet/go-ipfs/util"
|
|
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
|
|
)
|
|
|
|
var log = eventlog.Logger("conn")
|
|
|
|
// ReleaseBuffer puts the given byte array back into the buffer pool,
|
|
// first verifying that it is the correct size
|
|
func ReleaseBuffer(b []byte) {
|
|
log.Debugf("Releasing buffer! (cap,size = %d, %d)", cap(b), len(b))
|
|
mpool.ByteSlicePool.Put(uint32(cap(b)), b)
|
|
}
|
|
|
|
// singleConn represents a single connection to another Peer (IPFS Node).
|
|
type singleConn struct {
|
|
local peer.ID
|
|
remote peer.ID
|
|
maconn manet.Conn
|
|
msgrw msgio.ReadWriteCloser
|
|
event io.Closer
|
|
}
|
|
|
|
// newConn constructs a new connection
|
|
func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn) (Conn, error) {
|
|
ml := lgbl.Dial("conn", local, remote, maconn.LocalMultiaddr(), maconn.RemoteMultiaddr())
|
|
|
|
conn := &singleConn{
|
|
local: local,
|
|
remote: remote,
|
|
maconn: maconn,
|
|
msgrw: msgio.NewReadWriter(maconn),
|
|
event: log.EventBegin(ctx, "connLifetime", ml),
|
|
}
|
|
|
|
log.Debugf("newSingleConn %p: %v to %v", conn, local, remote)
|
|
return conn, nil
|
|
}
|
|
|
|
// close is the internal close function, called by ContextCloser.Close
|
|
func (c *singleConn) Close() error {
|
|
defer func() {
|
|
if c.event != nil {
|
|
c.event.Close()
|
|
c.event = nil
|
|
}
|
|
}()
|
|
|
|
// close underlying connection
|
|
return c.msgrw.Close()
|
|
}
|
|
|
|
// ID is an identifier unique to this connection.
|
|
func (c *singleConn) ID() string {
|
|
return ID(c)
|
|
}
|
|
|
|
func (c *singleConn) String() string {
|
|
return String(c, "singleConn")
|
|
}
|
|
|
|
func (c *singleConn) LocalAddr() net.Addr {
|
|
return c.maconn.LocalAddr()
|
|
}
|
|
|
|
func (c *singleConn) RemoteAddr() net.Addr {
|
|
return c.maconn.RemoteAddr()
|
|
}
|
|
|
|
func (c *singleConn) LocalPrivateKey() ic.PrivKey {
|
|
return nil
|
|
}
|
|
|
|
func (c *singleConn) RemotePublicKey() ic.PubKey {
|
|
return nil
|
|
}
|
|
|
|
func (c *singleConn) SetDeadline(t time.Time) error {
|
|
return c.maconn.SetDeadline(t)
|
|
}
|
|
func (c *singleConn) SetReadDeadline(t time.Time) error {
|
|
return c.maconn.SetReadDeadline(t)
|
|
}
|
|
|
|
func (c *singleConn) SetWriteDeadline(t time.Time) error {
|
|
return c.maconn.SetWriteDeadline(t)
|
|
}
|
|
|
|
// LocalMultiaddr is the Multiaddr on this side
|
|
func (c *singleConn) LocalMultiaddr() ma.Multiaddr {
|
|
return c.maconn.LocalMultiaddr()
|
|
}
|
|
|
|
// RemoteMultiaddr is the Multiaddr on the remote side
|
|
func (c *singleConn) RemoteMultiaddr() ma.Multiaddr {
|
|
return c.maconn.RemoteMultiaddr()
|
|
}
|
|
|
|
// LocalPeer is the Peer on this side
|
|
func (c *singleConn) LocalPeer() peer.ID {
|
|
return c.local
|
|
}
|
|
|
|
// RemotePeer is the Peer on the remote side
|
|
func (c *singleConn) RemotePeer() peer.ID {
|
|
return c.remote
|
|
}
|
|
|
|
// Read reads data, net.Conn style
|
|
func (c *singleConn) Read(buf []byte) (int, error) {
|
|
return c.msgrw.Read(buf)
|
|
}
|
|
|
|
// Write writes data, net.Conn style
|
|
func (c *singleConn) Write(buf []byte) (int, error) {
|
|
return c.msgrw.Write(buf)
|
|
}
|
|
|
|
func (c *singleConn) NextMsgLen() (int, error) {
|
|
return c.msgrw.NextMsgLen()
|
|
}
|
|
|
|
// ReadMsg reads data, net.Conn style
|
|
func (c *singleConn) ReadMsg() ([]byte, error) {
|
|
return c.msgrw.ReadMsg()
|
|
}
|
|
|
|
// WriteMsg writes data, net.Conn style
|
|
func (c *singleConn) WriteMsg(buf []byte) error {
|
|
return c.msgrw.WriteMsg(buf)
|
|
}
|
|
|
|
// ReleaseMsg releases a buffer
|
|
func (c *singleConn) ReleaseMsg(m []byte) {
|
|
c.msgrw.ReleaseMsg(m)
|
|
}
|
|
|
|
// ID returns the ID of a given Conn.
|
|
func ID(c Conn) string {
|
|
l := fmt.Sprintf("%s/%s", c.LocalMultiaddr(), c.LocalPeer().Pretty())
|
|
r := fmt.Sprintf("%s/%s", c.RemoteMultiaddr(), c.RemotePeer().Pretty())
|
|
lh := u.Hash([]byte(l))
|
|
rh := u.Hash([]byte(r))
|
|
ch := u.XOR(lh, rh)
|
|
return u.Key(ch).Pretty()
|
|
}
|
|
|
|
// String returns the user-friendly String representation of a conn
|
|
func String(c Conn, typ string) string {
|
|
return fmt.Sprintf("%s (%s) <-- %s %p --> (%s) %s",
|
|
c.LocalPeer(), c.LocalMultiaddr(), typ, c, c.RemoteMultiaddr(), c.RemotePeer())
|
|
}
|