conn.go 1.2 KB
Newer Older
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
package swarm

import (
  "fmt"
  "net"
  ma "github.com/jbenet/go-multiaddr"
  peer "github.com/jbenet/go-ipfs/peer"
  msgio "github.com/jbenet/go-msgio"
)

const ChanBuffer = 10

type Conn struct {
  Peer *peer.Peer
  Addr *ma.Multiaddr
  Conn net.Conn

  Closed chan bool
  Outgoing *msgio.Chan
  Incoming *msgio.Chan
}


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

  network, host, err := addr.DialArgs()
  if err != nil {
    return nil, err
  }

  nconn, err := net.Dial(network, host)
  if err != nil {
    return nil, err
  }

  out := msgio.NewChan(10)
  inc := msgio.NewChan(10)

  conn := &Conn{
    Peer: peer,
    Addr: addr,
    Conn: nconn,

    Outgoing: out,
    Incoming: inc,
    Closed: make(chan bool, 1),
  }

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

  return conn, nil
}

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

  // closing net connection
  err := s.Conn.Close()
  s.Conn = nil
  // closing channels
  s.Incoming.Close()
  s.Outgoing.Close()
  s.Closed<- true
  return err
}