@cryptotaxi247 / kubo / commits / 0e1824629

Make dns resolve paths under _dnslink.

Thus allowing to CNAME main site entry to gateway and stil specify dnslink. License: MIT Signed-off-by: Jakub Sztandera <kubuxu@gmail.com>

Kubuxu committed Jan 11, 2016 at 16:01 UTC 0e18246294bba0cba7055ebfb3058e82e78c2881
2 files changed +81 -10
namesys/dns.go
+53 -10
@@ -41,33 +41,76 @@ func (r *DNSResolver) ResolveN(ctx context.Context, name string, depth int) (pat
41 return resolve(ctx, r, name, depth, "/ipns/")
42 }
43
44 +type lookupRes struct {
45 + path path.Path
46 + error error
47 +}
48 +
49 // resolveOnce implements resolver.
50 // TXT records for a given domain name should contain a b58
51 // encoded multihash.
52 func (r *DNSResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) {
53 segments := strings.SplitN(name, "/", 2)
54 + domain := segments[0]
55
50 - if !isd.IsDomain(segments[0]) {
56 + if !isd.IsDomain(domain) {
57 return "", errors.New("not a valid domain name")
58 }
59 + log.Infof("DNSResolver resolving %s", domain)
60 +
61 + rootChan := make(chan lookupRes, 1)
62 + go workDomain(r, domain, rootChan)
63 +
64 + subChan := make(chan lookupRes, 1)
65 + go workDomain(r, "_dnslink."+domain, subChan)
66 +
67 + var subRes lookupRes
68 + select {
69 + case subRes = <-subChan:
70 + case <-ctx.Done():
71 + return "", ctx.Err()
72 + }
73 +
74 + var p path.Path
75 + if subRes.error == nil {
76 + p = subRes.path
77 + } else {
78 + var rootRes lookupRes
79 + select {
80 + case rootRes = <-rootChan:
81 + case <-ctx.Done():
82 + return "", ctx.Err()
83 + }
84 + if rootRes.error == nil {
85 + p = rootRes.path
86 + } else {
87 + return "", ErrResolveFailed
88 + }
89 + }
90 + if len(segments) > 1 {
91 + return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1])
92 + } else {
93 + return p, nil
94 + }
95 +}
96 +
97 +func workDomain(r *DNSResolver, name string, res chan lookupRes) {
98 + txt, err := r.lookupTXT(name)
99
54 - log.Infof("DNSResolver resolving %s", segments[0])
55 - txt, err := r.lookupTXT(segments[0])
100 if err != nil {
57 - return "", err
101 + // Error is != nil
102 + res <- lookupRes{"", err}
103 + return
104 }
105
106 for _, t := range txt {
107 p, err := parseEntry(t)
108 if err == nil {
63 - if len(segments) > 1 {
64 - return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1])
65 - }
66 - return p, nil
109 + res <- lookupRes{p, nil}
110 + return
111 }
112 }
69 -
70 - return "", ErrResolveFailed
113 + res <- lookupRes{"", ErrResolveFailed}
114 }
115
116 func parseEntry(txt string) (path.Path, error) {
namesys/dns_test.go
+28
@@ -65,6 +65,9 @@ func newMockDNS() *mockDNS {
65 "ipfs.example.com": []string{
66 "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
67 },
68 + "_dnslink.dipfs.example.com": []string{
69 + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
70 + },
71 "dns1.example.com": []string{
72 "dnslink=/ipns/ipfs.example.com",
73 },
@@ -85,6 +88,12 @@ func newMockDNS() *mockDNS {
88 "loop2.example.com": []string{
89 "dnslink=/ipns/loop1.example.com",
90 },
91 + "_dnslink.dloop1.example.com": []string{
92 + "dnslink=/ipns/loop2.example.com",
93 + },
94 + "_dnslink.dloop2.example.com": []string{
95 + "dnslink=/ipns/loop1.example.com",
96 + },
97 "bad.example.com": []string{
98 "dnslink=",
99 },
@@ -100,6 +109,18 @@ func newMockDNS() *mockDNS {
109 "withtrailingrec.example.com": []string{
110 "dnslink=/ipns/withtrailing.example.com/segment/",
111 },
112 + "double.example.com": []string{
113 + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
114 + },
115 + "_dnslink.double.example.com": []string{
116 + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
117 + },
118 + "double.conflict.com": []string{
119 + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
120 + },
121 + "_dnslink.conflict.example.com": []string{
122 + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE",
123 + },
124 },
125 }
126 }
@@ -109,6 +130,7 @@ func TestDNSResolution(t *testing.T) {
130 r := &DNSResolver{lookupTXT: mock.lookupTXT}
131 testResolution(t, r, "multihash.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
132 testResolution(t, r, "ipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
133 + testResolution(t, r, "dipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
134 testResolution(t, r, "dns1.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
135 testResolution(t, r, "dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
136 testResolution(t, r, "dns2.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
@@ -122,6 +144,10 @@ func TestDNSResolution(t *testing.T) {
144 testResolution(t, r, "loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
145 testResolution(t, r, "loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
146 testResolution(t, r, "loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
147 + testResolution(t, r, "dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
148 + testResolution(t, r, "dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
149 + testResolution(t, r, "dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
150 + testResolution(t, r, "dloop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
151 testResolution(t, r, "bad.example.com", DefaultDepthLimit, "", ErrResolveFailed)
152 testResolution(t, r, "withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil)
153 testResolution(t, r, "withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil)
@@ -129,4 +155,6 @@ func TestDNSResolution(t *testing.T) {
155 testResolution(t, r, "withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
156 testResolution(t, r, "withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
157 testResolution(t, r, "withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
158 + testResolution(t, r, "double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
159 + testResolution(t, r, "conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
160 }