mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-25 15:08:45 +08:00
begin planning of identification process
This commit is contained in:

committed by
Juan Batiz-Benet

parent
8203d2c0cf
commit
61f13ea7f7
28
identify/identify.go
Normal file
28
identify/identify.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// The identify package handles how peers identify with eachother upon
|
||||||
|
// connection to the network
|
||||||
|
package identify
|
||||||
|
|
||||||
|
import (
|
||||||
|
peer "github.com/jbenet/go-ipfs/peer"
|
||||||
|
swarm "github.com/jbenet/go-ipfs/swarm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Perform initial communication with this peer to share node ID's and
|
||||||
|
// initiate communication
|
||||||
|
func Handshake(self *peer.Peer, conn *swarm.Conn) error {
|
||||||
|
|
||||||
|
// temporary:
|
||||||
|
// put your own id in a 16byte buffer and send that over to
|
||||||
|
// the peer as your ID, then wait for them to send their ID.
|
||||||
|
// Once that trade is finished, the handshake is complete and
|
||||||
|
// both sides should 'trust' each other
|
||||||
|
|
||||||
|
id := make([]byte, 16)
|
||||||
|
copy(id, self.ID)
|
||||||
|
|
||||||
|
conn.Outgoing.MsgChan <- id
|
||||||
|
resp := <-conn.Incoming.MsgChan
|
||||||
|
conn.Peer.ID = peer.ID(resp)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
3
identify/message.proto
Normal file
3
identify/message.proto
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
message Identify {
|
||||||
|
required bytes id = 1;
|
||||||
|
}
|
@ -2,10 +2,14 @@ package dht
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
peer "github.com/jbenet/go-ipfs/peer"
|
peer "github.com/jbenet/go-ipfs/peer"
|
||||||
swarm "github.com/jbenet/go-ipfs/swarm"
|
swarm "github.com/jbenet/go-ipfs/swarm"
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
|
identify "github.com/jbenet/go-ipfs/identify"
|
||||||
|
|
||||||
|
ma "github.com/jbenet/go-multiaddr"
|
||||||
|
|
||||||
ds "github.com/jbenet/datastore.go"
|
ds "github.com/jbenet/datastore.go"
|
||||||
|
|
||||||
@ -35,15 +39,44 @@ type IpfsDHT struct {
|
|||||||
shutdown chan struct{}
|
shutdown chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDHT(p *peer.Peer) *IpfsDHT {
|
// Create a new DHT object with the given peer as the 'local' host
|
||||||
|
func NewDHT(p *peer.Peer) (*IpfsDHT, error) {
|
||||||
dht := new(IpfsDHT)
|
dht := new(IpfsDHT)
|
||||||
dht.self = p
|
|
||||||
dht.network = swarm.NewSwarm(p)
|
dht.network = swarm.NewSwarm(p)
|
||||||
|
//TODO: should Listen return an error?
|
||||||
|
dht.network.Listen()
|
||||||
|
|
||||||
|
dht.datastore = ds.NewMapDatastore()
|
||||||
|
|
||||||
|
dht.self = p
|
||||||
dht.listeners = make(map[uint64]chan *swarm.Message)
|
dht.listeners = make(map[uint64]chan *swarm.Message)
|
||||||
dht.shutdown = make(chan struct{})
|
dht.shutdown = make(chan struct{})
|
||||||
return dht
|
return dht, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect to a new peer at the given address
|
||||||
|
func (dht *IpfsDHT) Connect(addr *ma.Multiaddr) error {
|
||||||
|
peer := new(peer.Peer)
|
||||||
|
peer.AddAddress(addr)
|
||||||
|
|
||||||
|
conn,err := swarm.Dial("tcp", peer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = identify.Handshake(dht.self, conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dht.network.StartConn(conn.Peer.Key(), conn)
|
||||||
|
|
||||||
|
// TODO: Add this peer to our routing table
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read in all messages from swarm and handle them appropriately
|
// Read in all messages from swarm and handle them appropriately
|
||||||
// NOTE: this function is just a quick sketch
|
// NOTE: this function is just a quick sketch
|
||||||
func (dht *IpfsDHT) handleMessages() {
|
func (dht *IpfsDHT) handleMessages() {
|
||||||
@ -134,11 +167,9 @@ func (dht *IpfsDHT) handlePing(p *peer.Peer, pmes *DHTMessage) {
|
|||||||
resp := new(DHTMessage)
|
resp := new(DHTMessage)
|
||||||
resp.Id = pmes.Id
|
resp.Id = pmes.Id
|
||||||
resp.Response = &isResponse
|
resp.Response = &isResponse
|
||||||
|
resp.Type = pmes.Type
|
||||||
|
|
||||||
mes := new(swarm.Message)
|
dht.network.Chan.Outgoing <-swarm.NewMessage(p, []byte(resp.String()))
|
||||||
mes.Peer = p
|
|
||||||
mes.Data = []byte(resp.String())
|
|
||||||
dht.network.Chan.Outgoing <- mes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -162,9 +193,36 @@ func (dht *IpfsDHT) Unlisten(mesid uint64) {
|
|||||||
close(ch)
|
close(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Stop all communications from this node and shut down
|
// Stop all communications from this node and shut down
|
||||||
func (dht *IpfsDHT) Halt() {
|
func (dht *IpfsDHT) Halt() {
|
||||||
dht.shutdown <- struct{}{}
|
dht.shutdown <- struct{}{}
|
||||||
dht.network.Close()
|
dht.network.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ping a node, log the time it took
|
||||||
|
func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) {
|
||||||
|
// Thoughts: maybe this should accept an ID and do a peer lookup?
|
||||||
|
id := GenerateMessageID()
|
||||||
|
mes_type := DHTMessage_PING
|
||||||
|
pmes := new(DHTMessage)
|
||||||
|
pmes.Id = &id
|
||||||
|
pmes.Type = &mes_type
|
||||||
|
|
||||||
|
mes := new(swarm.Message)
|
||||||
|
mes.Peer = p
|
||||||
|
mes.Data = []byte(pmes.String())
|
||||||
|
|
||||||
|
before := time.Now()
|
||||||
|
response_chan := dht.ListenFor(id)
|
||||||
|
dht.network.Chan.Outgoing <- mes
|
||||||
|
|
||||||
|
tout := time.After(timeout)
|
||||||
|
select {
|
||||||
|
case <-response_chan:
|
||||||
|
roundtrip := time.Since(before)
|
||||||
|
u.DOut("Ping took %s.", roundtrip.String())
|
||||||
|
case <-tout:
|
||||||
|
// Timed out, think about removing node from network
|
||||||
|
u.DOut("Ping node timed out.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,11 +2,12 @@ package swarm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
peer "github.com/jbenet/go-ipfs/peer"
|
peer "github.com/jbenet/go-ipfs/peer"
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
ma "github.com/jbenet/go-multiaddr"
|
ma "github.com/jbenet/go-multiaddr"
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message represents a packet of information sent to or received from a
|
// Message represents a packet of information sent to or received from a
|
||||||
@ -19,6 +20,14 @@ type Message struct {
|
|||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleaner looking helper function to make a new message struct
|
||||||
|
func NewMessage(p *peer.Peer, data []byte) *Message {
|
||||||
|
return &Message{
|
||||||
|
Peer: p,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Chan is a swam channel, which provides duplex communication and errors.
|
// Chan is a swam channel, which provides duplex communication and errors.
|
||||||
type Chan struct {
|
type Chan struct {
|
||||||
Outgoing chan *Message
|
Outgoing chan *Message
|
||||||
@ -87,7 +96,8 @@ func (s *Swarm) connListen(maddr *ma.Multiaddr) error {
|
|||||||
for {
|
for {
|
||||||
nconn, err := list.Accept()
|
nconn, err := list.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
u.PErr("Failed to accept connection: %s - %s", netstr, addr)
|
u.PErr("Failed to accept connection: %s - %s [%s]", netstr,
|
||||||
|
addr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go s.handleNewConn(nconn)
|
go s.handleNewConn(nconn)
|
||||||
@ -99,7 +109,27 @@ func (s *Swarm) connListen(maddr *ma.Multiaddr) error {
|
|||||||
|
|
||||||
// Handle getting ID from this peer and adding it into the map
|
// Handle getting ID from this peer and adding it into the map
|
||||||
func (s *Swarm) handleNewConn(nconn net.Conn) {
|
func (s *Swarm) handleNewConn(nconn net.Conn) {
|
||||||
panic("Not yet implemented!")
|
p := MakePeerFromConn(nconn)
|
||||||
|
|
||||||
|
var addr *ma.Multiaddr
|
||||||
|
|
||||||
|
//naddr := nconn.RemoteAddr()
|
||||||
|
//addr := ma.FromDialArgs(naddr.Network(), naddr.String())
|
||||||
|
|
||||||
|
conn := &Conn{
|
||||||
|
Peer: p,
|
||||||
|
Addr: addr,
|
||||||
|
Conn: nconn,
|
||||||
|
}
|
||||||
|
|
||||||
|
newConnChans(conn)
|
||||||
|
go s.fanIn(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negotiate with peer for its ID and create a peer object
|
||||||
|
// TODO: this might belong in the peer package
|
||||||
|
func MakePeerFromConn(conn net.Conn) *peer.Peer {
|
||||||
|
panic("Not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes a swarm.
|
// Close closes a swarm.
|
||||||
@ -140,6 +170,11 @@ func (s *Swarm) Dial(peer *peer.Peer) (*Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.StartConn(k, conn)
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Swarm) StartConn(k u.Key, conn *Conn) {
|
||||||
// add to conns
|
// add to conns
|
||||||
s.connsLock.Lock()
|
s.connsLock.Lock()
|
||||||
s.conns[k] = conn
|
s.conns[k] = conn
|
||||||
@ -147,7 +182,6 @@ func (s *Swarm) Dial(peer *peer.Peer) (*Conn, error) {
|
|||||||
|
|
||||||
// kick off reader goroutine
|
// kick off reader goroutine
|
||||||
go s.fanIn(conn)
|
go s.fanIn(conn)
|
||||||
return conn, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles the unwrapping + sending of messages to the right connection.
|
// Handles the unwrapping + sending of messages to the right connection.
|
||||||
@ -165,7 +199,8 @@ func (s *Swarm) fanOut() {
|
|||||||
conn, found := s.conns[msg.Peer.Key()]
|
conn, found := s.conns[msg.Peer.Key()]
|
||||||
s.connsLock.RUnlock()
|
s.connsLock.RUnlock()
|
||||||
if !found {
|
if !found {
|
||||||
e := fmt.Errorf("Sent msg to peer without open conn: %v", msg.Peer)
|
e := fmt.Errorf("Sent msg to peer without open conn: %v",
|
||||||
|
msg.Peer)
|
||||||
s.Chan.Errors <- e
|
s.Chan.Errors <- e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user