conn.go 1.21 KB
Newer Older
1 2 3
package swarm

import (
4 5 6 7 8 9
	"fmt"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
	msgio "github.com/jbenet/go-msgio"
	ma "github.com/jbenet/go-multiaddr"
	"net"
10 11 12 13 14
)

const ChanBuffer = 10

type Conn struct {
15 16 17
	Peer *peer.Peer
	Addr *ma.Multiaddr
	Conn net.Conn
18

19 20 21
	Closed   chan bool
	Outgoing *msgio.Chan
	Incoming *msgio.Chan
22 23
}

24
type ConnMap map[u.Key]*Conn
25 26

func Dial(network string, peer *peer.Peer) (*Conn, error) {
27 28 29 30
	addr := peer.NetAddress(network)
	if addr == nil {
		return nil, fmt.Errorf("No address for network %s", network)
	}
31

32 33 34 35
	network, host, err := addr.DialArgs()
	if err != nil {
		return nil, err
	}
36

37 38 39 40
	nconn, err := net.Dial(network, host)
	if err != nil {
		return nil, err
	}
41

42 43
	out := msgio.NewChan(10)
	inc := msgio.NewChan(10)
44

45 46 47 48
	conn := &Conn{
		Peer: peer,
		Addr: addr,
		Conn: nconn,
49

50 51 52 53
		Outgoing: out,
		Incoming: inc,
		Closed:   make(chan bool, 1),
	}
54

55 56
	go out.WriteTo(nconn)
	go inc.ReadFrom(nconn, 1<<12)
57

58
	return conn, nil
59 60 61
}

func (s *Conn) Close() error {
62 63 64
	if s.Conn == nil {
		return fmt.Errorf("Already closed.") // already closed
	}
65

66 67 68 69 70 71 72 73
	// closing net connection
	err := s.Conn.Close()
	s.Conn = nil
	// closing channels
	s.Incoming.Close()
	s.Outgoing.Close()
	s.Closed <- true
	return err
74
}