func addressBytesToString(p Protocol, b []byte) (string, error) { switch p.Code { // ipv4,6 case P_IP4, P_IP6: return net.IP(b).String(), nil // tcp udp dccp sctp case P_TCP, P_UDP, P_DCCP, P_SCTP: i := binary.BigEndian.Uint16(b) return strconv.Itoa(int(i)), nil case P_IPFS: // ipfs // the address is a varint-prefixed multihash string representation size, n := ReadVarintCode(b) b = b[n:] if len(b) != size { panic("inconsistent lengths") } m, err := mh.Cast(b) if err != nil { return "", err } return m.B58String(), nil } return "", fmt.Errorf("unknown protocol") }
// resolveOnce implements resolver. Uses the IPFS routing system to // resolve SFS-like names. func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) { log.Debugf("RoutingResolve: '%s'", name) hash, err := mh.FromB58String(name) if err != nil { log.Warning("RoutingResolve: bad input hash: [%s]\n", name) return "", err } // name should be a multihash. if it isn't, error out here. // use the routing system to get the name. // /ipns/<name> h := []byte("/ipns/" + string(hash)) ipnsKey := key.Key(h) val, err := r.routing.GetValue(ctx, ipnsKey) if err != nil { log.Warning("RoutingResolve get failed.") return "", err } entry := new(pb.IpnsEntry) err = proto.Unmarshal(val, entry) if err != nil { return "", err } // name should be a public key retrievable from ipfs pubkey, err := routing.GetPublicKey(r.routing, ctx, hash) if err != nil { return "", err } hsh, _ := pubkey.Hash() log.Debugf("pk hash = %s", key.Key(hsh)) // check sig with pk if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok { return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey) } // ok sig checks out. this is a valid name. // check for old style record: valh, err := mh.Cast(entry.GetValue()) if err != nil { // Not a multihash, probably a new record return path.ParsePath(string(entry.GetValue())) } else { // Its an old style multihash record log.Warning("Detected old style multihash record") return path.FromKey(key.Key(valh)), nil } }
func Decode(encoding, digest string) (mh.Multihash, error) { switch encoding { case "raw": return mh.Cast([]byte(digest)) case "hex": return hex.DecodeString(digest) case "base58": return base58.Decode(digest), nil case "base64": return base64.StdEncoding.DecodeString(digest) default: return nil, fmt.Errorf("unknown encoding: %s", encoding) } }
func ParseKeyToPath(txt string) (Path, error) { if txt == "" { return "", ErrNoComponents } chk := b58.Decode(txt) if len(chk) == 0 { return "", errors.New("not a key") } if _, err := mh.Cast(chk); err != nil { return "", err } return FromKey(key.Key(chk)), nil }
// Unmarshal decodes raw data into a *Node instance. // The conversion uses an intermediate PBNode. func (n *Node) Unmarshal(encoded []byte) error { var pbn pb.PBNode if err := pbn.Unmarshal(encoded); err != nil { return fmt.Errorf("Unmarshal failed. %v", err) } pbnl := pbn.GetLinks() n.Links = make([]*Link, len(pbnl)) for i, l := range pbnl { n.Links[i] = &Link{Name: l.GetName(), Size: l.GetTsize()} h, err := mh.Cast(l.GetHash()) if err != nil { return fmt.Errorf("Link hash is not valid multihash. %v", err) } n.Links[i].Hash = h } sort.Stable(LinkSlice(n.Links)) // keep links sorted n.Data = pbn.GetData() return nil }
// IDFromBytes cast a string to ID type, and validate // the id to make sure it is a multihash. func IDFromBytes(b []byte) (ID, error) { if _, err := mh.Cast(b); err != nil { return ID(""), err } return ID(b), nil }
// IDFromString cast a string to ID type, and validate // the id to make sure it is a multihash. func IDFromString(s string) (ID, error) { if _, err := mh.Cast([]byte(s)); err != nil { return ID(""), err } return ID(s), nil }
// AllKeysChan runs a query for keys from the blockstore. // this is very simplistic, in the future, take dsq.Query as a param? // // AllKeysChan respects context func (bs *blockstore) AllKeysChan(ctx context.Context) (<-chan key.Key, error) { // KeysOnly, because that would be _a lot_ of data. q := dsq.Query{KeysOnly: true} // datastore/namespace does *NOT* fix up Query.Prefix q.Prefix = BlockPrefix.String() res, err := bs.datastore.Query(q) if err != nil { return nil, err } // this function is here to compartmentalize get := func() (k key.Key, ok bool) { select { case <-ctx.Done(): return k, false case e, more := <-res.Next(): if !more { return k, false } if e.Error != nil { log.Debug("blockstore.AllKeysChan got err:", e.Error) return k, false } // need to convert to key.Key using key.KeyFromDsKey. k = key.KeyFromDsKey(ds.NewKey(e.Key)) log.Debug("blockstore: query got key", k) // key must be a multihash. else ignore it. _, err := mh.Cast([]byte(k)) if err != nil { return "", true } return k, true } } output := make(chan key.Key) go func() { defer func() { res.Process().Close() // ensure exit (signals early exit, too) close(output) }() for { k, ok := get() if !ok { return } if k == "" { continue } select { case <-ctx.Done(): return case output <- k: } } }() return output, nil }