Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Commit 59eb235

Browse files
whyrusleepingjbenet
authored andcommitted
implement namesys resolvers (thanks to bren2010 for dns and proquint)
0 parents  commit 59eb235

File tree

7 files changed

+212
-0
lines changed

7 files changed

+212
-0
lines changed

dns.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package namesys
2+
3+
import (
4+
"net"
5+
"strings"
6+
7+
u "github.com/jbenet/go-ipfs/util"
8+
)
9+
10+
type DNSResolver struct {
11+
// TODO: maybe some sort of caching?
12+
// cache would need a timeout
13+
}
14+
15+
func (r *DNSResolver) Resolve(name string) (string, error) {
16+
txt, err := net.LookupTXT(name)
17+
if err != nil {
18+
return "", err
19+
}
20+
21+
for _, t := range txt {
22+
pair := strings.Split(t, "=")
23+
if len(pair) < 2 {
24+
// Log error?
25+
u.DErr("Incorrectly formatted text record.")
26+
continue
27+
}
28+
if pair[0] == name {
29+
return pair[1], nil
30+
}
31+
}
32+
return "", u.ErrNotFound
33+
}

entry.pb.go

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

entry.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package namesys;
2+
3+
message InpsEntry {
4+
required bytes value = 1;
5+
required bytes signature = 2;
6+
}

nsresolver.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package namesys
2+
3+
type NSResolver interface {
4+
Resolve(string) (string, error)
5+
}

proquint.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package namesys
2+
3+
import (
4+
"errors"
5+
6+
proquint "github.com/bren2010/proquint"
7+
)
8+
9+
var _ = proquint.Encode
10+
11+
type ProquintResolver struct{}
12+
13+
func (r *ProquintResolver) Resolve(name string) (string, error) {
14+
ok, err := proquint.IsProquint(name)
15+
if err != nil {
16+
return "", err
17+
}
18+
if !ok {
19+
return "", errors.New("not a valid proquint string")
20+
}
21+
return string(proquint.Decode(name)), nil
22+
}

resolver.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package namesys
2+
3+
import "strings"
4+
5+
type MasterResolver struct {
6+
dns *DNSResolver
7+
routing *RoutingResolver
8+
pro *ProquintResolver
9+
}
10+
11+
func (mr *MasterResolver) Resolve(name string) (string, error) {
12+
if strings.Contains(name, ".") {
13+
return mr.dns.Resolve(name)
14+
}
15+
16+
if strings.Contains(name, "-") {
17+
return mr.pro.Resolve(name)
18+
}
19+
20+
return mr.routing.Resolve(name)
21+
}

routing.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package namesys
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"code.google.com/p/goprotobuf/proto"
8+
9+
ci "github.com/jbenet/go-ipfs/crypto"
10+
mdag "github.com/jbenet/go-ipfs/merkledag"
11+
"github.com/jbenet/go-ipfs/routing"
12+
u "github.com/jbenet/go-ipfs/util"
13+
mh "github.com/jbenet/go-multihash"
14+
)
15+
16+
// RoutingName is the de-serialized name structure that is stored (serialized)
17+
// in the routing system. Basically, a hash + a digital signature. (serialization can be
18+
// protobuf, or a simple binary format)
19+
type RoutingName struct {
20+
Hash u.Key
21+
Signature []byte
22+
}
23+
24+
// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
25+
type RoutingResolver struct {
26+
routing routing.IpfsRouting
27+
dag mdag.DAGService
28+
}
29+
30+
func (r *RoutingResolver) Resolve(name string) (string, error) {
31+
hash, err := mh.FromB58String(name)
32+
if err != nil {
33+
return "", err
34+
}
35+
// name should be a multihash. if it isn't, error out here.
36+
37+
// use the routing system to get the name.
38+
// /ipns/<name>
39+
h, err := u.Hash([]byte("ipns:" + name))
40+
if err != nil {
41+
return "", err
42+
}
43+
44+
inpsKey := u.Key(h)
45+
val, err := r.routing.GetValue(inpsKey, time.Second*10)
46+
if err != nil {
47+
return "", err
48+
}
49+
50+
entry := new(InpsEntry)
51+
err = proto.Unmarshal(val, entry)
52+
if err != nil {
53+
return "", err
54+
}
55+
56+
// name should be a public key retrievable from ipfs
57+
// /ipfs/<name>
58+
key := u.Key(hash)
59+
node, err := r.dag.Get(key)
60+
if err != nil {
61+
return "", err
62+
}
63+
64+
// get PublicKey from node.Data
65+
pk, err := ci.UnmarshalPublicKey(node.Data)
66+
if err != nil {
67+
return "", err
68+
}
69+
70+
// check sig with pk
71+
if ok, err := pk.Verify(entry.GetValue(), entry.GetSignature()); err != nil && ok {
72+
return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
73+
}
74+
75+
// ok sig checks out. this is a valid name.
76+
return string(entry.GetValue()), nil
77+
}

0 commit comments

Comments
 (0)