// FindPeer searches for a peer with given ID. func (dht *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, error) { // Check if were already connected to them p, _ := dht.Find(id) if p != nil { return p, nil } routeLevel := 0 p = dht.routingTables[routeLevel].NearestPeer(kb.ConvertPeerID(id)) if p == nil { return nil, kb.ErrLookupFailure } if p.ID.Equal(id) { return p, nil } for routeLevel < len(dht.routingTables) { pmes, err := dht.findPeerSingle(p, id, timeout, routeLevel) plist := pmes.GetPeers() if plist == nil || len(plist) == 0 { routeLevel++ continue } found := plist[0] addr, err := ma.NewMultiaddr(found.GetAddr()) if err != nil { return nil, err } nxtPeer, err := dht.network.GetConnection(peer.ID(found.GetId()), addr) if err != nil { return nil, err } if pmes.GetSuccess() { if !id.Equal(nxtPeer.ID) { return nil, errors.New("got back invalid peer from 'successful' response") } return nxtPeer, nil } p = nxtPeer } return nil, u.ErrNotFound }
// GetConnection will check if we are already connected to the peer in question // and only open a new connection if we arent already func (s *Swarm) GetConnection(id peer.ID, addr *ma.Multiaddr) (*peer.Peer, error) { p := &peer.Peer{ ID: id, Addresses: []*ma.Multiaddr{addr}, } if id.Equal(s.local.ID) { panic("Attempted connection to self!") } conn, err, reused := s.Dial(p) if err != nil { return nil, err } if reused { return p, nil } err = s.handleDialedCon(conn) return conn.Peer, err }