mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-25 12:27:43 +08:00
89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package swarm
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
|
|
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"
|
|
)
|
|
|
|
// ChanBuffer is the size of the buffer in the Conn Chan
|
|
const ChanBuffer = 10
|
|
|
|
// Conn represents a connection to another Peer (IPFS Node).
|
|
type Conn struct {
|
|
Peer *peer.Peer
|
|
Addr *ma.Multiaddr
|
|
Conn net.Conn
|
|
|
|
Closed chan bool
|
|
Outgoing *msgio.Chan
|
|
Incoming *msgio.Chan
|
|
}
|
|
|
|
// ConnMap maps Keys (Peer.IDs) to Connections.
|
|
type ConnMap map[u.Key]*Conn
|
|
|
|
// Dial connects to a particular peer, over a given network
|
|
// Example: Dial("udp", peer)
|
|
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
|
|
}
|
|
|
|
conn := &Conn{
|
|
Peer: peer,
|
|
Addr: addr,
|
|
Conn: nconn,
|
|
}
|
|
|
|
newConnChans(conn)
|
|
return conn, nil
|
|
}
|
|
|
|
// Construct new channels for given Conn.
|
|
func newConnChans(c *Conn) error {
|
|
if c.Outgoing != nil || c.Incoming != nil {
|
|
return fmt.Errorf("Conn already initialized")
|
|
}
|
|
|
|
c.Outgoing = msgio.NewChan(10)
|
|
c.Incoming = msgio.NewChan(10)
|
|
c.Closed = make(chan bool, 1)
|
|
|
|
go c.Outgoing.WriteTo(c.Conn)
|
|
go c.Incoming.ReadFrom(c.Conn, 1<<12)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close closes the connection, and associated channels.
|
|
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
|
|
}
|