1package madns 2 3import ( 4 "context" 5 "net" 6 "testing" 7 8 ma "github.com/multiformats/go-multiaddr" 9) 10 11var ip4a = net.IPAddr{IP: net.ParseIP("192.0.2.1")} 12var ip4b = net.IPAddr{IP: net.ParseIP("192.0.2.2")} 13var ip6a = net.IPAddr{IP: net.ParseIP("2001:db8::a3")} 14var ip6b = net.IPAddr{IP: net.ParseIP("2001:db8::a4")} 15 16var ip4ma = ma.StringCast("/ip4/" + ip4a.IP.String()) 17var ip4mb = ma.StringCast("/ip4/" + ip4b.IP.String()) 18var ip6ma = ma.StringCast("/ip6/" + ip6a.IP.String()) 19var ip6mb = ma.StringCast("/ip6/" + ip6b.IP.String()) 20 21var txtmc = ma.Join(ip4ma, ma.StringCast("/tcp/123/http")) 22var txtmd = ma.Join(ip4ma, ma.StringCast("/tcp/123")) 23var txtme = ma.Join(ip4ma, ma.StringCast("/tcp/789/http")) 24 25var txta = "dnsaddr=" + ip4ma.String() 26var txtb = "dnsaddr=" + ip6ma.String() 27var txtc = "dnsaddr=" + txtmc.String() 28var txtd = "dnsaddr=" + txtmd.String() 29var txte = "dnsaddr=" + txtme.String() 30 31func makeResolver() *Resolver { 32 mock := &MockBackend{ 33 IP: map[string][]net.IPAddr{ 34 "example.com": []net.IPAddr{ip4a, ip4b, ip6a, ip6b}, 35 }, 36 TXT: map[string][]string{ 37 "_dnsaddr.example.com": []string{txta, txtb}, 38 "_dnsaddr.matching.com": []string{txtc, txtd, txte, "not a dnsaddr", "dnsaddr=/foobar"}, 39 }, 40 } 41 resolver := &Resolver{Backend: mock} 42 return resolver 43} 44 45func TestMatches(t *testing.T) { 46 if !Matches(ma.StringCast("/tcp/1234/dns6/example.com")) { 47 // Pretend this is a p2p-circuit address. Unfortunately, we'd 48 // need to depend on the circuit package to parse it. 49 t.Fatalf("expected match, didn't: /tcp/1234/dns6/example.com") 50 } 51 if !Matches(ma.StringCast("/dns/example.com")) { 52 t.Fatalf("expected match, didn't: /dns/example.com") 53 } 54 if !Matches(ma.StringCast("/dns4/example.com")) { 55 t.Fatalf("expected match, didn't: /dns4/example.com") 56 } 57 if !Matches(ma.StringCast("/dns6/example.com")) { 58 t.Fatalf("expected match, didn't: /dns6/example.com") 59 } 60 if !Matches(ma.StringCast("/dnsaddr/example.com")) { 61 t.Fatalf("expected match, didn't: /dnsaddr/example.com") 62 } 63 if Matches(ip4ma) { 64 t.Fatalf("expected no-match, but did: %s", ip4ma.String()) 65 } 66} 67 68func TestSimpleIPResolve(t *testing.T) { 69 ctx := context.Background() 70 resolver := makeResolver() 71 72 addrs4, err := resolver.Resolve(ctx, ma.StringCast("/dns4/example.com")) 73 if err != nil { 74 t.Error(err) 75 } 76 if len(addrs4) != 2 || !addrs4[0].Equal(ip4ma) || addrs4[0].Equal(ip4mb) { 77 t.Fatalf("expected [%s %s], got %+v", ip4ma, ip4mb, addrs4) 78 } 79 80 addrs6, err := resolver.Resolve(ctx, ma.StringCast("/dns6/example.com")) 81 if err != nil { 82 t.Error(err) 83 } 84 if len(addrs6) != 2 || !addrs6[0].Equal(ip6ma) || addrs6[0].Equal(ip6mb) { 85 t.Fatalf("expected [%s %s], got %+v", ip6ma, ip6mb, addrs6) 86 } 87 88 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dns/example.com")) 89 if err != nil { 90 t.Error(err) 91 } 92 for i, expected := range []ma.Multiaddr{ip4ma, ip4mb, ip6ma, ip6mb} { 93 if !expected.Equal(addrs[i]) { 94 t.Fatalf("%d: expected %s, got %s", i, expected, addrs[i]) 95 } 96 } 97} 98 99func TestResolveMultiple(t *testing.T) { 100 ctx := context.Background() 101 resolver := makeResolver() 102 103 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dns4/example.com/quic/dns6/example.com")) 104 if err != nil { 105 t.Error(err) 106 } 107 for i, x := range []ma.Multiaddr{ip4ma, ip4mb} { 108 for j, y := range []ma.Multiaddr{ip6ma, ip6mb} { 109 expected := ma.Join(x, ma.StringCast("/quic"), y) 110 actual := addrs[i*2+j] 111 if !expected.Equal(actual) { 112 t.Fatalf("expected %s, got %s", expected, actual) 113 } 114 } 115 } 116} 117 118func TestResolveMultipleAdjacent(t *testing.T) { 119 ctx := context.Background() 120 resolver := makeResolver() 121 122 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dns4/example.com/dns6/example.com")) 123 if err != nil { 124 t.Error(err) 125 } 126 for i, x := range []ma.Multiaddr{ip4ma, ip4mb} { 127 for j, y := range []ma.Multiaddr{ip6ma, ip6mb} { 128 expected := ma.Join(x, y) 129 actual := addrs[i*2+j] 130 if !expected.Equal(actual) { 131 t.Fatalf("expected %s, got %s", expected, actual) 132 } 133 } 134 } 135} 136 137func TestResolveMultipleSandwitch(t *testing.T) { 138 ctx := context.Background() 139 resolver := makeResolver() 140 141 addrs, err := resolver.Resolve(ctx, ma.StringCast("/quic/dns4/example.com/dns6/example.com/http")) 142 if err != nil { 143 t.Error(err) 144 } 145 for i, x := range []ma.Multiaddr{ip4ma, ip4mb} { 146 for j, y := range []ma.Multiaddr{ip6ma, ip6mb} { 147 expected := ma.Join(ma.StringCast("/quic"), x, y, ma.StringCast("/http")) 148 actual := addrs[i*2+j] 149 if !expected.Equal(actual) { 150 t.Fatalf("expected %s, got %s", expected, actual) 151 } 152 } 153 } 154} 155 156func TestSimpleTXTResolve(t *testing.T) { 157 ctx := context.Background() 158 resolver := makeResolver() 159 160 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dnsaddr/example.com")) 161 if err != nil { 162 t.Error(err) 163 } 164 if len(addrs) != 2 || !addrs[0].Equal(ip4ma) || addrs[0].Equal(ip6ma) { 165 t.Fatalf("expected [%s %s], got %+v", ip4ma, ip6ma, addrs) 166 } 167} 168 169func TestNonResolvable(t *testing.T) { 170 ctx := context.Background() 171 resolver := makeResolver() 172 173 addrs, err := resolver.Resolve(ctx, ip4ma) 174 if err != nil { 175 t.Error(err) 176 } 177 if len(addrs) != 1 || !addrs[0].Equal(ip4ma) { 178 t.Fatalf("expected [%s], got %+v", ip4ma, addrs) 179 } 180} 181 182func TestLongMatch(t *testing.T) { 183 ctx := context.Background() 184 resolver := makeResolver() 185 186 res, err := resolver.Resolve(ctx, ma.StringCast("/dnsaddr/example.com/quic/quic/quic/quic")) 187 if err != nil { 188 t.Error(err) 189 } 190 if len(res) != 0 { 191 t.Error("expected no results") 192 } 193} 194 195func TestEmptyResult(t *testing.T) { 196 ctx := context.Background() 197 resolver := makeResolver() 198 199 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dnsaddr/none.com")) 200 if err != nil { 201 t.Error(err) 202 } 203 if len(addrs) > 0 { 204 t.Fatalf("expected [], got %+v", addrs) 205 } 206} 207 208func TestDnsaddrMatching(t *testing.T) { 209 ctx := context.Background() 210 resolver := makeResolver() 211 212 addrs, err := resolver.Resolve(ctx, ma.StringCast("/dnsaddr/matching.com/tcp/123/http")) 213 if err != nil { 214 t.Error(err) 215 } 216 if len(addrs) != 1 || !addrs[0].Equal(txtmc) { 217 t.Fatalf("expected [%s], got %+v", txtmc, addrs) 218 } 219 220 addrs, err = resolver.Resolve(ctx, ma.StringCast("/dnsaddr/matching.com/tcp/123")) 221 if err != nil { 222 t.Error(err) 223 } 224 if len(addrs) != 1 || !addrs[0].Equal(txtmd) { 225 t.Fatalf("expected [%s], got %+v", txtmd, addrs) 226 } 227} 228 229func TestBadDomain(t *testing.T) { 230 bts := ma.StringCast("/dns4/example.com").Bytes() 231 bts[len(bts)-5] = '/' 232 _, err := ma.NewMultiaddrBytes(bts) 233 if err == nil { 234 t.Error("expected malformed address to fail to parse") 235 } 236} 237