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  }