Example #1
0
func (dht *IpfsDHT) handleAddProvider(p peer.Peer, pmes *pb.Message) (*pb.Message, error) {
	key := u.Key(pmes.GetKey())

	log.Debugf("%s adding %s as a provider for '%s'\n", dht.self, p, peer.ID(key))

	// add provider should use the address given in the message
	for _, pb := range pmes.GetProviderPeers() {
		pid := peer.ID(pb.GetId())
		if pid.Equal(p.ID()) {

			addr, err := pb.Address()
			if err != nil {
				log.Errorf("provider %s error with address %s", p, *pb.Addr)
				continue
			}

			log.Infof("received provider %s %s for %s", p, addr, key)
			p.AddAddress(addr)
			dht.providers.AddProvider(key, p)

		} else {
			log.Errorf("handleAddProvider received provider %s from %s", pid, p)
		}
	}

	return pmes, nil // send back same msg as confirmation.
}
func TestClientFindProviders(t *testing.T) {
	peer := peer.WithIDString("42")
	rs := VirtualRoutingServer()
	client := rs.Client(peer)

	k := u.Key("hello")
	err := client.Provide(context.Background(), k)
	if err != nil {
		t.Fatal(err)
	}
	max := 100

	providersFromHashTable := rs.Providers(k)

	isInHT := false
	for _, p := range providersFromHashTable {
		if bytes.Equal(p.ID(), peer.ID()) {
			isInHT = true
		}
	}
	if !isInHT {
		t.Fatal("Despite client providing key, peer wasn't in hash table as a provider")
	}
	providersFromClient := client.FindProvidersAsync(context.Background(), u.Key("hello"), max)
	isInClient := false
	for p := range providersFromClient {
		if bytes.Equal(p.ID(), peer.ID()) {
			isInClient = true
		}
	}
	if !isInClient {
		t.Fatal("Despite client providing key, client didn't receive peer when finding providers")
	}
}
Example #3
0
func (dht *IpfsDHT) handleFindPeer(p peer.Peer, pmes *pb.Message) (*pb.Message, error) {
	resp := pb.NewMessage(pmes.GetType(), "", pmes.GetClusterLevel())
	var closest []peer.Peer

	// if looking for self... special case where we send it on CloserPeers.
	if peer.ID(pmes.GetKey()).Equal(dht.self.ID()) {
		closest = []peer.Peer{dht.self}
	} else {
		closest = dht.betterPeersToQuery(pmes, CloserPeerCount)
	}

	if closest == nil {
		log.Errorf("handleFindPeer: could not find anything.")
		return resp, nil
	}

	var withAddresses []peer.Peer
	for _, p := range closest {
		if len(p.Addresses()) > 0 {
			withAddresses = append(withAddresses, p)
		}
	}

	for _, p := range withAddresses {
		log.Debugf("handleFindPeer: sending back '%s'", p)
	}
	resp.CloserPeers = pb.PeersToPBPeers(withAddresses)
	return resp, nil
}
func newPeer(t *testing.T, id string) peer.Peer {
	mh, err := mh.FromHexString(id)
	if err != nil {
		t.Error(err)
		return nil
	}

	return peer.WithID(peer.ID(mh))
}
func TestProviderManager(t *testing.T) {
	ctx := context.Background()
	mid := peer.ID("testing")
	p := NewProviderManager(ctx, mid)
	a := u.Key("test")
	p.AddProvider(a, peer.WithIDString("testingprovider"))
	resp := p.GetProviders(a)
	if len(resp) != 1 {
		t.Fatal("Could not retrieve provider.")
	}
	p.Close()
}
Example #6
0
// Bootstrap builds up list of peers by requesting random peer IDs
func (dht *IpfsDHT) Bootstrap(ctx context.Context) {
	id := make([]byte, 16)
	rand.Read(id)
	p, err := dht.FindPeer(ctx, peer.ID(id))
	if err != nil {
		log.Error("Bootstrap peer error: %s", err)
	}
	err = dht.dialer.DialPeer(ctx, p)
	if err != nil {
		log.Errorf("Bootstrap peer error: %s", err)
	}
}
func TestSetAndGet(t *testing.T) {
	pid := peer.ID([]byte("the peer id"))
	p := peer.WithID(pid)
	k := u.Key("42")
	rs := VirtualRoutingServer()
	err := rs.Announce(p, k)
	if err != nil {
		t.Fatal(err)
	}
	providers := rs.Providers(k)
	if len(providers) != 1 {
		t.Fatal("should be one")
	}
	for _, elem := range providers {
		if bytes.Equal(elem.ID(), pid) {
			return
		}
	}
	t.Fatal("ID should have matched")
}
Example #8
0
// peerFromInfo returns a peer using info in the protobuf peer struct
// to lookup or create a peer
func (dht *IpfsDHT) peerFromInfo(pbp *pb.Message_Peer) (peer.Peer, error) {

	id := peer.ID(pbp.GetId())

	// bail out if it's ourselves
	//TODO(jbenet) not sure this should be an error _here_
	if id.Equal(dht.self.ID()) {
		return nil, errors.New("found self")
	}

	p, err := dht.getPeer(id)
	if err != nil {
		return nil, err
	}

	maddr, err := pbp.Address()
	if err != nil {
		return nil, err
	}
	p.AddAddress(maddr)
	return p, nil
}
Example #9
0
func (dht *IpfsDHT) verifyRecord(r *pb.Record) error {
	// First, validate the signature
	p, err := dht.peerstore.Get(peer.ID(r.GetAuthor()))
	if err != nil {
		return err
	}
	k := u.Key(r.GetKey())

	blob := bytes.Join([][]byte{[]byte(k),
		r.GetValue(),
		[]byte(r.GetAuthor())}, []byte{})

	ok, err := p.PubKey().Verify(blob, r.GetSignature())
	if err != nil {
		log.Error("Signature verify failed.")
		return err
	}

	if !ok {
		return ErrBadRecord
	}

	// Now, check validity func
	parts := strings.Split(r.GetKey(), "/")
	if len(parts) < 3 {
		log.Errorf("Record had bad key: %s", u.Key(r.GetKey()))
		return ErrBadRecord
	}

	fnc, ok := dht.Validators[parts[1]]
	if !ok {
		log.Errorf("Unrecognized key prefix: %s", parts[1])
		return ErrInvalidRecordType
	}

	return fnc(u.Key(r.GetKey()), r.GetValue())
}
Example #10
0
func initIdentity(cfg *config.Identity, peers peer.Peerstore, online bool) (peer.Peer, error) {
	if cfg.PeerID == "" {
		return nil, debugerror.New("Identity was not set in config (was ipfs init run?)")
	}

	if len(cfg.PeerID) == 0 {
		return nil, debugerror.New("No peer ID in config! (was ipfs init run?)")
	}

	// get peer from peerstore (so it is constructed there)
	id := peer.ID(b58.Decode(cfg.PeerID))
	self, err := peers.Get(id)
	if err != nil {
		return nil, err
	}
	self.SetType(peer.Local)
	self, err = peers.Add(self)
	if err != nil {
		return nil, err
	}

	self.SetVersions(handshake.ClientVersion, handshake.IpfsVersion.String())

	// when not online, don't need to parse private keys (yet)
	if online {
		skb, err := base64.StdEncoding.DecodeString(cfg.PrivKey)
		if err != nil {
			return nil, err
		}

		if err := self.LoadAndVerifyKeyPair(skb); err != nil {
			return nil, err
		}
	}

	return self, nil
}
Example #11
0
// Looks for race conditions in table operations. For a more 'certain'
// test, increase the loop counter from 1000 to a much higher number
// and set GOMAXPROCS above 1
func TestTableMultithreaded(t *testing.T) {
	local := peer.ID("localPeer")
	tab := NewRoutingTable(20, ConvertPeerID(local), time.Hour)
	var peers []peer.Peer
	for i := 0; i < 500; i++ {
		peers = append(peers, tu.RandPeer())
	}

	done := make(chan struct{})
	go func() {
		for i := 0; i < 1000; i++ {
			n := rand.Intn(len(peers))
			tab.Update(peers[n])
		}
		done <- struct{}{}
	}()

	go func() {
		for i := 0; i < 1000; i++ {
			n := rand.Intn(len(peers))
			tab.Update(peers[n])
		}
		done <- struct{}{}
	}()

	go func() {
		for i := 0; i < 1000; i++ {
			n := rand.Intn(len(peers))
			tab.Find(peers[n].ID())
		}
		done <- struct{}{}
	}()
	<-done
	<-done
	<-done
}
Example #12
0
func newPeerTime(t time.Time) peer.Peer {
	s := fmt.Sprintf("hmmm time: %v", t)
	h := u.Hash([]byte(s))
	return peer.WithID(peer.ID(h))
}
Example #13
0
	Arguments: []cmds.Argument{
		cmds.StringArg("peerid", false, false, "peer.ID of node to look up"),
	},
	Run: func(req cmds.Request) (interface{}, error) {
		node, err := req.Context().GetNode()
		if err != nil {
			return nil, err
		}

		if len(req.Arguments()) == 0 {
			return printPeer(node.Identity)
		}

		pid := req.Arguments()[0]

		id := peer.ID(b58.Decode(pid))
		if len(id) == 0 {
			return nil, cmds.ClientError("Invalid peer id")
		}

		ctx, _ := context.WithTimeout(context.TODO(), time.Second*5)
		if node.Routing == nil {
			return nil, errors.New(offlineIdErrorMessage)
		}

		p, err := node.Routing.FindPeer(ctx, id)
		if err == kb.ErrLookupFailure {
			return nil, errors.New(offlineIdErrorMessage)
		}
		if err != nil {
			return nil, err
Example #14
0
// Find specific Peer
// FindPeer searches for a peer with given ID.
func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (peer.Peer, error) {

	// Check if were already connected to them
	p, _ := dht.FindLocal(id)
	if p != nil {
		return p, nil
	}

	routeLevel := 0
	closest := dht.routingTables[routeLevel].NearestPeers(kb.ConvertPeerID(id), AlphaValue)
	if closest == nil || len(closest) == 0 {
		return nil, kb.ErrLookupFailure
	}

	// Sanity...
	for _, p := range closest {
		if p.ID().Equal(id) {
			log.Error("Found target peer in list of closest peers...")
			return p, nil
		}
	}

	// setup the Query
	query := newQuery(u.Key(id), dht.dialer, func(ctx context.Context, p peer.Peer) (*dhtQueryResult, error) {

		pmes, err := dht.findPeerSingle(ctx, p, id, routeLevel)
		if err != nil {
			return nil, err
		}

		closer := pmes.GetCloserPeers()
		var clpeers []peer.Peer
		for _, pbp := range closer {
			np, err := dht.getPeer(peer.ID(pbp.GetId()))
			if err != nil {
				log.Warningf("Received invalid peer from query: %v", err)
				continue
			}
			ma, err := pbp.Address()
			if err != nil {
				log.Warning("Received peer with bad or missing address.")
				continue
			}
			np.AddAddress(ma)
			if pbp.GetId() == string(id) {
				return &dhtQueryResult{
					peer:    np,
					success: true,
				}, nil
			}
			clpeers = append(clpeers, np)
		}

		return &dhtQueryResult{closerPeers: clpeers}, nil
	})

	// run it!
	result, err := query.Run(ctx, closest)
	if err != nil {
		return nil, err
	}

	log.Debugf("FindPeer %v %v", id, result.success)
	if result.peer == nil {
		return nil, routing.ErrNotFound
	}

	return result.peer, nil
}
Example #15
0
func RandPeer() peer.Peer {
	id := make([]byte, 16)
	crand.Read(id)
	mhid := u.Hash(id)
	return peer.WithID(peer.ID(mhid))
}