github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/namesys/routing.go (about) 1 package namesys 2 3 import ( 4 "fmt" 5 6 proto "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/proto" 7 mh "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" 8 "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 9 10 key "github.com/ipfs/go-ipfs/blocks/key" 11 pb "github.com/ipfs/go-ipfs/namesys/pb" 12 path "github.com/ipfs/go-ipfs/path" 13 routing "github.com/ipfs/go-ipfs/routing" 14 u "github.com/ipfs/go-ipfs/util" 15 ) 16 17 var log = u.Logger("namesys") 18 19 // routingResolver implements NSResolver for the main IPFS SFS-like naming 20 type routingResolver struct { 21 routing routing.IpfsRouting 22 } 23 24 // NewRoutingResolver constructs a name resolver using the IPFS Routing system 25 // to implement SFS-like naming on top. 26 func NewRoutingResolver(route routing.IpfsRouting) Resolver { 27 if route == nil { 28 panic("attempt to create resolver with nil routing system") 29 } 30 31 return &routingResolver{routing: route} 32 } 33 34 // newRoutingResolver returns a resolver instead of a Resolver. 35 func newRoutingResolver(route routing.IpfsRouting) resolver { 36 if route == nil { 37 panic("attempt to create resolver with nil routing system") 38 } 39 40 return &routingResolver{routing: route} 41 } 42 43 // Resolve implements Resolver. 44 func (r *routingResolver) Resolve(ctx context.Context, name string) (path.Path, error) { 45 return r.ResolveN(ctx, name, DefaultDepthLimit) 46 } 47 48 // ResolveN implements Resolver. 49 func (r *routingResolver) ResolveN(ctx context.Context, name string, depth int) (path.Path, error) { 50 return resolve(ctx, r, name, depth, "/ipns/") 51 } 52 53 // resolveOnce implements resolver. Uses the IPFS routing system to 54 // resolve SFS-like names. 55 func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) { 56 log.Debugf("RoutingResolve: '%s'", name) 57 hash, err := mh.FromB58String(name) 58 if err != nil { 59 log.Warning("RoutingResolve: bad input hash: [%s]\n", name) 60 return "", err 61 } 62 // name should be a multihash. if it isn't, error out here. 63 64 // use the routing system to get the name. 65 // /ipns/<name> 66 h := []byte("/ipns/" + string(hash)) 67 68 ipnsKey := key.Key(h) 69 val, err := r.routing.GetValue(ctx, ipnsKey) 70 if err != nil { 71 log.Warning("RoutingResolve get failed.") 72 return "", err 73 } 74 75 entry := new(pb.IpnsEntry) 76 err = proto.Unmarshal(val, entry) 77 if err != nil { 78 return "", err 79 } 80 81 // name should be a public key retrievable from ipfs 82 pubkey, err := routing.GetPublicKey(r.routing, ctx, hash) 83 if err != nil { 84 return "", err 85 } 86 87 hsh, _ := pubkey.Hash() 88 log.Debugf("pk hash = %s", key.Key(hsh)) 89 90 // check sig with pk 91 if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok { 92 return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey) 93 } 94 95 // ok sig checks out. this is a valid name. 96 97 // check for old style record: 98 valh, err := mh.Cast(entry.GetValue()) 99 if err != nil { 100 // Not a multihash, probably a new record 101 return path.ParsePath(string(entry.GetValue())) 102 } else { 103 // Its an old style multihash record 104 log.Warning("Detected old style multihash record") 105 return path.FromKey(key.Key(valh)), nil 106 } 107 }