1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-30 01:52:26 +08:00

implement namesys resolvers (thanks to bren2010 for dns and proquint)

This commit is contained in:
Jeromy
2014-09-10 16:55:49 +00:00
committed by Juan Batiz-Benet
parent 0d84af554e
commit 235a767492
9 changed files with 257 additions and 1 deletions

44
cmd/ipfs/pin.go Normal file
View File

@ -0,0 +1,44 @@
package main
import (
"os"
"github.com/gonuts/flag"
"github.com/jbenet/commander"
"github.com/jbenet/go-ipfs/daemon"
u "github.com/jbenet/go-ipfs/util"
)
var cmdIpfsPin = &commander.Command{
UsageLine: "pin",
Short: "pin an ipfs object to local storage.",
Long: `ipfs pin <ipfs-path> - pin ipfs object to local storage.
Retrieves the object named by <ipfs-path> and stores it locally
on disk.
`,
Run: pinCmd,
Flag: *flag.NewFlagSet("ipfs-pin", flag.ExitOnError),
}
func pinCmd(c *commander.Command, inp []string) error {
if len(inp) < 1 {
u.POut(c.Long)
return nil
}
com := daemon.NewCommand()
com.Command = "pin"
com.Args = inp
err := daemon.SendCommand(com, "localhost:12345")
if err != nil {
n, err := localNode(false)
if err != nil {
return err
}
daemon.ExecuteCommand(com, n, os.Stdout)
}
return nil
}

View File

@ -60,7 +60,7 @@ type IpfsNode struct {
Resolver *path.Resolver
// the name system, resolves paths to hashes
// Namesys *namesys.Namesys
Namesys namesys.NSResolver
}
// NewIpfsNode constructs a new IpfsNode based on the given config.

33
namesys/dns.go Normal file
View File

@ -0,0 +1,33 @@
package namesys
import (
"net"
"strings"
u "github.com/jbenet/go-ipfs/util"
)
type DNSResolver struct {
// TODO: maybe some sort of caching?
// cache would need a timeout
}
func (r *DNSResolver) Resolve(name string) (string, error) {
txt, err := net.LookupTXT(name)
if err != nil {
return "", err
}
for _, t := range txt {
pair := strings.Split(t, "=")
if len(pair) < 2 {
// Log error?
u.DErr("Incorrectly formatted text record.")
continue
}
if pair[0] == name {
return pair[1], nil
}
}
return "", u.ErrNotFound
}

48
namesys/entry.pb.go Normal file
View File

@ -0,0 +1,48 @@
// Code generated by protoc-gen-go.
// source: entry.proto
// DO NOT EDIT!
/*
Package namesys is a generated protocol buffer package.
It is generated from these files:
entry.proto
It has these top-level messages:
InpsEntry
*/
package namesys
import proto "code.google.com/p/goprotobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type InpsEntry struct {
Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *InpsEntry) Reset() { *m = InpsEntry{} }
func (m *InpsEntry) String() string { return proto.CompactTextString(m) }
func (*InpsEntry) ProtoMessage() {}
func (m *InpsEntry) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func (m *InpsEntry) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func init() {
}

6
namesys/entry.proto Normal file
View File

@ -0,0 +1,6 @@
package namesys;
message InpsEntry {
required bytes value = 1;
required bytes signature = 2;
}

5
namesys/nsresolver.go Normal file
View File

@ -0,0 +1,5 @@
package namesys
type NSResolver interface {
Resolve(string) (string, error)
}

22
namesys/proquint.go Normal file
View File

@ -0,0 +1,22 @@
package namesys
import (
"errors"
proquint "github.com/bren2010/proquint"
)
var _ = proquint.Encode
type ProquintResolver struct{}
func (r *ProquintResolver) Resolve(name string) (string, error) {
ok, err := proquint.IsProquint(name)
if err != nil {
return "", err
}
if !ok {
return "", errors.New("not a valid proquint string")
}
return string(proquint.Decode(name)), nil
}

21
namesys/resolver.go Normal file
View File

@ -0,0 +1,21 @@
package namesys
import "strings"
type MasterResolver struct {
dns *DNSResolver
routing *RoutingResolver
pro *ProquintResolver
}
func (mr *MasterResolver) Resolve(name string) (string, error) {
if strings.Contains(name, ".") {
return mr.dns.Resolve(name)
}
if strings.Contains(name, "-") {
return mr.pro.Resolve(name)
}
return mr.routing.Resolve(name)
}

77
namesys/routing.go Normal file
View File

@ -0,0 +1,77 @@
package namesys
import (
"fmt"
"time"
"code.google.com/p/goprotobuf/proto"
ci "github.com/jbenet/go-ipfs/crypto"
mdag "github.com/jbenet/go-ipfs/merkledag"
"github.com/jbenet/go-ipfs/routing"
u "github.com/jbenet/go-ipfs/util"
mh "github.com/jbenet/go-multihash"
)
// RoutingName is the de-serialized name structure that is stored (serialized)
// in the routing system. Basically, a hash + a digital signature. (serialization can be
// protobuf, or a simple binary format)
type RoutingName struct {
Hash u.Key
Signature []byte
}
// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
type RoutingResolver struct {
routing routing.IpfsRouting
dag mdag.DAGService
}
func (r *RoutingResolver) Resolve(name string) (string, error) {
hash, err := mh.FromB58String(name)
if err != nil {
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, err := u.Hash([]byte("ipns:" + name))
if err != nil {
return "", err
}
inpsKey := u.Key(h)
val, err := r.routing.GetValue(inpsKey, time.Second*10)
if err != nil {
return "", err
}
entry := new(InpsEntry)
err = proto.Unmarshal(val, entry)
if err != nil {
return "", err
}
// name should be a public key retrievable from ipfs
// /ipfs/<name>
key := u.Key(hash)
node, err := r.dag.Get(key)
if err != nil {
return "", err
}
// get PublicKey from node.Data
pk, err := ci.UnmarshalPublicKey(node.Data)
if err != nil {
return "", err
}
// check sig with pk
if ok, err := pk.Verify(entry.GetValue(), entry.GetSignature()); err != nil && ok {
return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
}
// ok sig checks out. this is a valid name.
return string(entry.GetValue()), nil
}