github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/net/conn/conn.go (about)

     1  package conn
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net"
     7  	"time"
     8  
     9  	msgio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
    10  	mpool "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
    11  	ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
    12  	manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
    13  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    14  	ic "github.com/ipfs/go-ipfs/p2p/crypto"
    15  	peer "github.com/ipfs/go-ipfs/p2p/peer"
    16  	eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
    17  	u "github.com/ipfs/go-ipfs/util"
    18  	lgbl "github.com/ipfs/go-ipfs/util/eventlog/loggables"
    19  )
    20  
    21  var log = eventlog.Logger("conn")
    22  
    23  // ReleaseBuffer puts the given byte array back into the buffer pool,
    24  // first verifying that it is the correct size
    25  func ReleaseBuffer(b []byte) {
    26  	log.Debugf("Releasing buffer! (cap,size = %d, %d)", cap(b), len(b))
    27  	mpool.ByteSlicePool.Put(uint32(cap(b)), b)
    28  }
    29  
    30  // singleConn represents a single connection to another Peer (IPFS Node).
    31  type singleConn struct {
    32  	local  peer.ID
    33  	remote peer.ID
    34  	maconn manet.Conn
    35  	msgrw  msgio.ReadWriteCloser
    36  	event  io.Closer
    37  }
    38  
    39  // newConn constructs a new connection
    40  func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn) (Conn, error) {
    41  	ml := lgbl.Dial("conn", local, remote, maconn.LocalMultiaddr(), maconn.RemoteMultiaddr())
    42  
    43  	conn := &singleConn{
    44  		local:  local,
    45  		remote: remote,
    46  		maconn: maconn,
    47  		msgrw:  msgio.NewReadWriter(maconn),
    48  		event:  log.EventBegin(ctx, "connLifetime", ml),
    49  	}
    50  
    51  	log.Debugf("newSingleConn %p: %v to %v", conn, local, remote)
    52  	return conn, nil
    53  }
    54  
    55  // close is the internal close function, called by ContextCloser.Close
    56  func (c *singleConn) Close() error {
    57  	defer func() {
    58  		if c.event != nil {
    59  			c.event.Close()
    60  			c.event = nil
    61  		}
    62  	}()
    63  
    64  	// close underlying connection
    65  	return c.msgrw.Close()
    66  }
    67  
    68  // ID is an identifier unique to this connection.
    69  func (c *singleConn) ID() string {
    70  	return ID(c)
    71  }
    72  
    73  func (c *singleConn) String() string {
    74  	return String(c, "singleConn")
    75  }
    76  
    77  func (c *singleConn) LocalAddr() net.Addr {
    78  	return c.maconn.LocalAddr()
    79  }
    80  
    81  func (c *singleConn) RemoteAddr() net.Addr {
    82  	return c.maconn.RemoteAddr()
    83  }
    84  
    85  func (c *singleConn) LocalPrivateKey() ic.PrivKey {
    86  	return nil
    87  }
    88  
    89  func (c *singleConn) RemotePublicKey() ic.PubKey {
    90  	return nil
    91  }
    92  
    93  func (c *singleConn) SetDeadline(t time.Time) error {
    94  	return c.maconn.SetDeadline(t)
    95  }
    96  func (c *singleConn) SetReadDeadline(t time.Time) error {
    97  	return c.maconn.SetReadDeadline(t)
    98  }
    99  
   100  func (c *singleConn) SetWriteDeadline(t time.Time) error {
   101  	return c.maconn.SetWriteDeadline(t)
   102  }
   103  
   104  // LocalMultiaddr is the Multiaddr on this side
   105  func (c *singleConn) LocalMultiaddr() ma.Multiaddr {
   106  	return c.maconn.LocalMultiaddr()
   107  }
   108  
   109  // RemoteMultiaddr is the Multiaddr on the remote side
   110  func (c *singleConn) RemoteMultiaddr() ma.Multiaddr {
   111  	return c.maconn.RemoteMultiaddr()
   112  }
   113  
   114  // LocalPeer is the Peer on this side
   115  func (c *singleConn) LocalPeer() peer.ID {
   116  	return c.local
   117  }
   118  
   119  // RemotePeer is the Peer on the remote side
   120  func (c *singleConn) RemotePeer() peer.ID {
   121  	return c.remote
   122  }
   123  
   124  // Read reads data, net.Conn style
   125  func (c *singleConn) Read(buf []byte) (int, error) {
   126  	return c.msgrw.Read(buf)
   127  }
   128  
   129  // Write writes data, net.Conn style
   130  func (c *singleConn) Write(buf []byte) (int, error) {
   131  	return c.msgrw.Write(buf)
   132  }
   133  
   134  func (c *singleConn) NextMsgLen() (int, error) {
   135  	return c.msgrw.NextMsgLen()
   136  }
   137  
   138  // ReadMsg reads data, net.Conn style
   139  func (c *singleConn) ReadMsg() ([]byte, error) {
   140  	return c.msgrw.ReadMsg()
   141  }
   142  
   143  // WriteMsg writes data, net.Conn style
   144  func (c *singleConn) WriteMsg(buf []byte) error {
   145  	return c.msgrw.WriteMsg(buf)
   146  }
   147  
   148  // ReleaseMsg releases a buffer
   149  func (c *singleConn) ReleaseMsg(m []byte) {
   150  	c.msgrw.ReleaseMsg(m)
   151  }
   152  
   153  // ID returns the ID of a given Conn.
   154  func ID(c Conn) string {
   155  	l := fmt.Sprintf("%s/%s", c.LocalMultiaddr(), c.LocalPeer().Pretty())
   156  	r := fmt.Sprintf("%s/%s", c.RemoteMultiaddr(), c.RemotePeer().Pretty())
   157  	lh := u.Hash([]byte(l))
   158  	rh := u.Hash([]byte(r))
   159  	ch := u.XOR(lh, rh)
   160  	return peer.ID(ch).Pretty()
   161  }
   162  
   163  // String returns the user-friendly String representation of a conn
   164  func String(c Conn, typ string) string {
   165  	return fmt.Sprintf("%s (%s) <-- %s %p --> (%s) %s",
   166  		c.LocalPeer(), c.LocalMultiaddr(), typ, c, c.RemoteMultiaddr(), c.RemotePeer())
   167  }