net.go 2.23 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
package net

import (
	"errors"

	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"

	context "code.google.com/p/go.net/context"
)

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

	// local peer
	local *peer.Peer

	// protocol multiplexing
	muxer *mux.Muxer

	// peer connection multiplexing
	swarm *swarm.Swarm

	// network context
	ctx    context.Context
	cancel context.CancelFunc
}

// NewIpfsNetwork is the structure that implements the network interface
func NewIpfsNetwork(ctx context.Context, local *peer.Peer,
	pmap *mux.ProtocolMap) (*IpfsNetwork, error) {

	ctx, cancel := context.WithCancel(ctx)

	in := &IpfsNetwork{
		local:  local,
		muxer:  &mux.Muxer{Protocols: *pmap},
		ctx:    ctx,
		cancel: cancel,
	}

	err := in.muxer.Start(ctx)
	if err != nil {
		cancel()
		return nil, err
	}

	in.swarm, err = swarm.NewSwarm(ctx, local)
	if err != nil {
		cancel()
		return nil, err
	}

	return in, nil
}

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

// DialPeer attempts to establish a connection to a given peer
func (n *IpfsNetwork) DialPeer(p *peer.Peer) error {
	_, err := n.swarm.Dial(p)
	return err
}

// ClosePeer connection to peer
func (n *IpfsNetwork) ClosePeer(p *peer.Peer) error {
	return n.swarm.CloseConnection(p)
}

// IsConnected returns whether a connection to given peer exists.
func (n *IpfsNetwork) IsConnected(p *peer.Peer) (bool, error) {
	return n.swarm.GetConnection(p.ID) != nil, nil
}

// 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
func (n *IpfsNetwork) SendMessage(m *msg.Message) error {
	n.swarm.Outgoing <- m
	return nil
}

// Close terminates all network operation
func (n *IpfsNetwork) Close() error {
	if n.cancel == nil {
		return errors.New("Network already closed.")
	}

	n.swarm.Close()
	n.muxer.Stop()

	n.cancel()
	n.cancel = nil
	return nil
}