net.go 4.03 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1
// Package net provides an interface for ipfs to interact with the network through
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
2 3 4
package net

import (
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
5
	conn "github.com/jbenet/go-ipfs/net/conn"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
6 7 8 9
	msg "github.com/jbenet/go-ipfs/net/message"
	mux "github.com/jbenet/go-ipfs/net/mux"
	swarm "github.com/jbenet/go-ipfs/net/swarm"
	peer "github.com/jbenet/go-ipfs/peer"
10
	util "github.com/jbenet/go-ipfs/util"
11
	ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12

13
	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
14
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15 16 17 18 19 20
)

// IpfsNetwork implements the Network interface,
type IpfsNetwork struct {

	// local peer
21
	local peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22 23 24 25 26 27 28

	// protocol multiplexing
	muxer *mux.Muxer

	// peer connection multiplexing
	swarm *swarm.Swarm

29 30
	// network context closer
	ctxc.ContextCloser
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
31 32 33
}

// NewIpfsNetwork is the structure that implements the network interface
34
func NewIpfsNetwork(ctx context.Context, listen []ma.Multiaddr, local peer.Peer,
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35
	peers peer.Peerstore, pmap *mux.ProtocolMap) (*IpfsNetwork, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
36 37

	in := &IpfsNetwork{
38 39 40
		local:         local,
		muxer:         mux.NewMuxer(ctx, *pmap),
		ContextCloser: ctxc.NewContextCloser(ctx, nil),
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
41 42
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
43
	var err error
44
	in.swarm, err = swarm.NewSwarm(ctx, listen, local, peers)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
45
	if err != nil {
46
		in.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
47 48 49
		return nil, err
	}

50 51 52
	in.AddCloserChild(in.swarm)
	in.AddCloserChild(in.muxer)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
53 54 55
	// remember to wire components together.
	in.muxer.Pipe.ConnectTo(in.swarm.Pipe)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56 57 58 59 60 61
	return in, nil
}

// Listen handles incoming connections on given Multiaddr.
// func (n *IpfsNetwork) Listen(*ma.Muliaddr) error {}

62 63
// DialPeer attempts to establish a connection to a given peer.
// Respects the context.
64
func (n *IpfsNetwork) DialPeer(ctx context.Context, p peer.Peer) error {
65
	err := util.ContextDo(ctx, func() error {
66 67 68
		_, err := n.swarm.Dial(p)
		return err
	})
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
69 70 71
	return err
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
72 73 74 75 76
// LocalPeer the network's LocalPeer
func (n *IpfsNetwork) LocalPeer() peer.Peer {
	return n.swarm.LocalPeer()
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77
// ClosePeer connection to peer
78
func (n *IpfsNetwork) ClosePeer(p peer.Peer) error {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
79 80 81 82
	return n.swarm.CloseConnection(p)
}

// IsConnected returns whether a connection to given peer exists.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
83 84
func (n *IpfsNetwork) IsConnected(p peer.Peer) bool {
	return n.swarm.GetConnection(p.ID()) != nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
85 86 87 88 89 90 91 92 93 94 95 96 97
}

// GetProtocols returns the protocols registered in the network.
func (n *IpfsNetwork) GetProtocols() *mux.ProtocolMap {
	// copy over because this map should be read only.
	pmap := mux.ProtocolMap{}
	for id, proto := range n.muxer.Protocols {
		pmap[id] = proto
	}
	return &pmap
}

// SendMessage sends given Message out
98
func (n *IpfsNetwork) SendMessage(m msg.NetMessage) error {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
99 100 101 102
	n.swarm.Outgoing <- m
	return nil
}

103 104
// GetPeerList returns the networks list of connected peers
func (n *IpfsNetwork) GetPeerList() []peer.Peer {
105
	return n.swarm.GetPeerList()
Jeromy's avatar
Jeromy committed
106
}
107

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
108 109 110 111 112
// GetConnections returns the networks list of open connections
func (n *IpfsNetwork) GetConnections() []conn.Conn {
	return n.swarm.Connections()
}

113
// GetBandwidthTotals returns the total amount of bandwidth transferred
114 115 116
func (n *IpfsNetwork) GetBandwidthTotals() (in uint64, out uint64) {
	return n.muxer.GetBandwidthTotals()
}
117

Jeromy's avatar
Jeromy committed
118 119 120 121 122
// GetBandwidthTotals returns the total amount of messages transferred
func (n *IpfsNetwork) GetMessageCounts() (in uint64, out uint64) {
	return n.muxer.GetMessageCounts()
}

123 124 125 126 127 128 129 130 131 132 133
// ListenAddresses returns a list of addresses at which this network listens.
func (n *IpfsNetwork) ListenAddresses() []ma.Multiaddr {
	return n.swarm.ListenAddresses()
}

// InterfaceListenAddresses returns a list of addresses at which this network
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func (n *IpfsNetwork) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
	return n.swarm.InterfaceListenAddresses()
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
134 135 136 137 138 139 140 141 142

// Connectedness returns a state signaling connection capabilities
// For now only returns Connecter || NotConnected. Expand into more later.
func (n *IpfsNetwork) Connectedness(p peer.Peer) Connectedness {
	if n.swarm.GetConnection(p.ID()) != nil {
		return Connected
	}
	return NotConnected
}