1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2020, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
30*cfb92d14SAndroid Build Coastguard Worker
31*cfb92d14SAndroid Build Coastguard Worker #include <openthread/config.h>
32*cfb92d14SAndroid Build Coastguard Worker
33*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
34*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
37*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
38*cfb92d14SAndroid Build Coastguard Worker #include "net/dns_types.hpp"
39*cfb92d14SAndroid Build Coastguard Worker
40*cfb92d14SAndroid Build Coastguard Worker namespace ot {
41*cfb92d14SAndroid Build Coastguard Worker
TestDnsName(void)42*cfb92d14SAndroid Build Coastguard Worker void TestDnsName(void)
43*cfb92d14SAndroid Build Coastguard Worker {
44*cfb92d14SAndroid Build Coastguard Worker enum
45*cfb92d14SAndroid Build Coastguard Worker {
46*cfb92d14SAndroid Build Coastguard Worker kMaxSize = 300,
47*cfb92d14SAndroid Build Coastguard Worker kMaxNameLength = Dns::Name::kMaxNameSize - 1,
48*cfb92d14SAndroid Build Coastguard Worker };
49*cfb92d14SAndroid Build Coastguard Worker
50*cfb92d14SAndroid Build Coastguard Worker struct TestName
51*cfb92d14SAndroid Build Coastguard Worker {
52*cfb92d14SAndroid Build Coastguard Worker const char *mName;
53*cfb92d14SAndroid Build Coastguard Worker uint16_t mEncodedLength;
54*cfb92d14SAndroid Build Coastguard Worker const uint8_t *mEncodedData;
55*cfb92d14SAndroid Build Coastguard Worker const char **mLabels;
56*cfb92d14SAndroid Build Coastguard Worker const char *mExpectedReadName;
57*cfb92d14SAndroid Build Coastguard Worker };
58*cfb92d14SAndroid Build Coastguard Worker
59*cfb92d14SAndroid Build Coastguard Worker struct TestMatches
60*cfb92d14SAndroid Build Coastguard Worker {
61*cfb92d14SAndroid Build Coastguard Worker const char *mFullName;
62*cfb92d14SAndroid Build Coastguard Worker const char *mFirstLabel;
63*cfb92d14SAndroid Build Coastguard Worker const char *mLabels;
64*cfb92d14SAndroid Build Coastguard Worker const char *mDomain;
65*cfb92d14SAndroid Build Coastguard Worker bool mShouldMatch;
66*cfb92d14SAndroid Build Coastguard Worker };
67*cfb92d14SAndroid Build Coastguard Worker
68*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
69*cfb92d14SAndroid Build Coastguard Worker MessagePool *messagePool;
70*cfb92d14SAndroid Build Coastguard Worker Message *message;
71*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
72*cfb92d14SAndroid Build Coastguard Worker uint16_t len;
73*cfb92d14SAndroid Build Coastguard Worker uint16_t offset;
74*cfb92d14SAndroid Build Coastguard Worker Dns::Name::LabelBuffer label;
75*cfb92d14SAndroid Build Coastguard Worker uint8_t labelLength;
76*cfb92d14SAndroid Build Coastguard Worker Dns::Name::Buffer name;
77*cfb92d14SAndroid Build Coastguard Worker const char *subDomain;
78*cfb92d14SAndroid Build Coastguard Worker const char *domain;
79*cfb92d14SAndroid Build Coastguard Worker const char *domain2;
80*cfb92d14SAndroid Build Coastguard Worker const char *fullName;
81*cfb92d14SAndroid Build Coastguard Worker const char *suffixName;
82*cfb92d14SAndroid Build Coastguard Worker Dns::Name dnsName;
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName1[] = {7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0};
85*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName2[] = {3, 'f', 'o', 'o', 1, 'a', 2, 'b', 'b', 3, 'e', 'd', 'u', 0};
86*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName3[] = {10, 'f', 'o', 'u', 'n', 'd', 'a', 't', 'i', 'o', 'n', 0};
87*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName4[] = {0};
88*cfb92d14SAndroid Build Coastguard Worker
89*cfb92d14SAndroid Build Coastguard Worker static const char *kLabels1[] = {"example", "com", nullptr};
90*cfb92d14SAndroid Build Coastguard Worker static const char *kLabels2[] = {"foo", "a", "bb", "edu", nullptr};
91*cfb92d14SAndroid Build Coastguard Worker static const char *kLabels3[] = {"foundation", nullptr};
92*cfb92d14SAndroid Build Coastguard Worker static const char *kLabels4[] = {nullptr};
93*cfb92d14SAndroid Build Coastguard Worker
94*cfb92d14SAndroid Build Coastguard Worker static const TestName kTestNames[] = {
95*cfb92d14SAndroid Build Coastguard Worker {"example.com", sizeof(kEncodedName1), kEncodedName1, kLabels1, "example.com."},
96*cfb92d14SAndroid Build Coastguard Worker {"example.com.", sizeof(kEncodedName1), kEncodedName1, kLabels1, "example.com."},
97*cfb92d14SAndroid Build Coastguard Worker {"foo.a.bb.edu", sizeof(kEncodedName2), kEncodedName2, kLabels2, "foo.a.bb.edu."},
98*cfb92d14SAndroid Build Coastguard Worker {"foo.a.bb.edu.", sizeof(kEncodedName2), kEncodedName2, kLabels2, "foo.a.bb.edu."},
99*cfb92d14SAndroid Build Coastguard Worker {"foundation", sizeof(kEncodedName3), kEncodedName3, kLabels3, "foundation."},
100*cfb92d14SAndroid Build Coastguard Worker {"foundation.", sizeof(kEncodedName3), kEncodedName3, kLabels3, "foundation."},
101*cfb92d14SAndroid Build Coastguard Worker {"", sizeof(kEncodedName4), kEncodedName4, kLabels4, "."},
102*cfb92d14SAndroid Build Coastguard Worker {".", sizeof(kEncodedName4), kEncodedName4, kLabels4, "."},
103*cfb92d14SAndroid Build Coastguard Worker {nullptr, sizeof(kEncodedName4), kEncodedName4, kLabels4, "."},
104*cfb92d14SAndroid Build Coastguard Worker };
105*cfb92d14SAndroid Build Coastguard Worker
106*cfb92d14SAndroid Build Coastguard Worker static const char *kMaxLengthNames[] = {
107*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken."
108*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken."
109*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken."
110*cfb92d14SAndroid Build Coastguard Worker "SorcererAndMagicia.",
111*cfb92d14SAndroid Build Coastguard Worker
112*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken."
113*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken."
114*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken."
115*cfb92d14SAndroid Build Coastguard Worker "SorcererAndMagicia",
116*cfb92d14SAndroid Build Coastguard Worker };
117*cfb92d14SAndroid Build Coastguard Worker
118*cfb92d14SAndroid Build Coastguard Worker static const char *kInvalidNames[] = {
119*cfb92d14SAndroid Build Coastguard Worker "foo..bar",
120*cfb92d14SAndroid Build Coastguard Worker "..",
121*cfb92d14SAndroid Build Coastguard Worker "a..",
122*cfb92d14SAndroid Build Coastguard Worker "..b",
123*cfb92d14SAndroid Build Coastguard Worker
124*cfb92d14SAndroid Build Coastguard Worker // Long label
125*cfb92d14SAndroid Build Coastguard Worker "a.an-invalid-very-long-label-string-with-more-than-sixty-four-characters.com",
126*cfb92d14SAndroid Build Coastguard Worker
127*cfb92d14SAndroid Build Coastguard Worker // Long name (more than 255 characters)
128*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken."
129*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken."
130*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken."
131*cfb92d14SAndroid Build Coastguard Worker "SorcererAndMagician.NoEyesCanEverSee.AnArtfulConjurer.MySenseFromMeTaken."
132*cfb92d14SAndroid Build Coastguard Worker "MyEyesWillNeverSee.BeautiesOfTheWholeWorld.BeholdWhoseVisionFine.MySightFromMeTaken"
133*cfb92d14SAndroid Build Coastguard Worker "PoemByRumiMolana",
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Worker // Long name of 255 characters which ends with a dot
136*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken."
137*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken."
138*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken."
139*cfb92d14SAndroid Build Coastguard Worker "SorcererAndMagician.",
140*cfb92d14SAndroid Build Coastguard Worker
141*cfb92d14SAndroid Build Coastguard Worker // Long name of 254 characters which does not end with a dot
142*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken."
143*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken."
144*cfb92d14SAndroid Build Coastguard Worker "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken."
145*cfb92d14SAndroid Build Coastguard Worker "SorcererAndMagician",
146*cfb92d14SAndroid Build Coastguard Worker
147*cfb92d14SAndroid Build Coastguard Worker };
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Worker static const char kBadLabel[] = "badlabel";
150*cfb92d14SAndroid Build Coastguard Worker static const char kBadName[] = "bad.name";
151*cfb92d14SAndroid Build Coastguard Worker
152*cfb92d14SAndroid Build Coastguard Worker static const TestMatches kTestMatches[] = {
153*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "foo", "bar", "local.", true},
154*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", nullptr, "foo.bar", "local.", true},
155*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "foo", "ba", "local.", false},
156*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "fooooo", "bar", "local.", false},
157*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "foo", "bar", "locall.", false},
158*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "f", "bar", "local.", false},
159*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "foo", "barr", "local.", false},
160*cfb92d14SAndroid Build Coastguard Worker {"foo.bar.local.", "foo", "bar", ".local.", false},
161*cfb92d14SAndroid Build Coastguard Worker {"My Lovely Instance._mt._udp.local.", "mY lovely instancE", "_mt._udp", "local.", true},
162*cfb92d14SAndroid Build Coastguard Worker {"My Lovely Instance._mt._udp.local.", nullptr, "mY lovely instancE._mt._udp", "local.", true},
163*cfb92d14SAndroid Build Coastguard Worker {"_s1._sub._srv._udp.default.service.arpa.", "_s1", "_sub._srv._udp", "default.service.arpa.", true},
164*cfb92d14SAndroid Build Coastguard Worker };
165*cfb92d14SAndroid Build Coastguard Worker
166*cfb92d14SAndroid Build Coastguard Worker printf("================================================================\n");
167*cfb92d14SAndroid Build Coastguard Worker printf("TestDnsName()\n");
168*cfb92d14SAndroid Build Coastguard Worker
169*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
170*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
171*cfb92d14SAndroid Build Coastguard Worker
172*cfb92d14SAndroid Build Coastguard Worker messagePool = &instance->Get<MessagePool>();
173*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
174*cfb92d14SAndroid Build Coastguard Worker
175*cfb92d14SAndroid Build Coastguard Worker message->SetOffset(0);
176*cfb92d14SAndroid Build Coastguard Worker
177*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
178*cfb92d14SAndroid Build Coastguard Worker printf("Verify domain name match:\n");
179*cfb92d14SAndroid Build Coastguard Worker
180*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local.";
181*cfb92d14SAndroid Build Coastguard Worker domain = "local.";
182*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
183*cfb92d14SAndroid Build Coastguard Worker
184*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local";
185*cfb92d14SAndroid Build Coastguard Worker domain = "local.";
186*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
187*cfb92d14SAndroid Build Coastguard Worker
188*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local.";
189*cfb92d14SAndroid Build Coastguard Worker domain = "local";
190*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
191*cfb92d14SAndroid Build Coastguard Worker
192*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local";
193*cfb92d14SAndroid Build Coastguard Worker domain = "local";
194*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.default.service.arpa.";
197*cfb92d14SAndroid Build Coastguard Worker domain = "default.service.arpa.";
198*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
199*cfb92d14SAndroid Build Coastguard Worker
200*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.default.service.arpa.";
201*cfb92d14SAndroid Build Coastguard Worker domain = "service.arpa.";
202*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
203*cfb92d14SAndroid Build Coastguard Worker
204*cfb92d14SAndroid Build Coastguard Worker // Verify it doesn't match a portion of a label.
205*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.default.service.arpa.";
206*cfb92d14SAndroid Build Coastguard Worker domain = "vice.arpa.";
207*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSubDomainOf(subDomain, domain));
208*cfb92d14SAndroid Build Coastguard Worker
209*cfb92d14SAndroid Build Coastguard Worker // Validate case does not matter
210*cfb92d14SAndroid Build Coastguard Worker
211*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local.";
212*cfb92d14SAndroid Build Coastguard Worker domain = "LOCAL.";
213*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
214*cfb92d14SAndroid Build Coastguard Worker
215*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local";
216*cfb92d14SAndroid Build Coastguard Worker domain = "LOCAL.";
217*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
218*cfb92d14SAndroid Build Coastguard Worker
219*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local.";
220*cfb92d14SAndroid Build Coastguard Worker domain = "LOCAL";
221*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
222*cfb92d14SAndroid Build Coastguard Worker
223*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.local";
224*cfb92d14SAndroid Build Coastguard Worker domain = "LOCAL";
225*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
226*cfb92d14SAndroid Build Coastguard Worker
227*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.Default.Service.ARPA.";
228*cfb92d14SAndroid Build Coastguard Worker domain = "dEFAULT.Service.arpa.";
229*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
230*cfb92d14SAndroid Build Coastguard Worker
231*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.default.service.ARpa.";
232*cfb92d14SAndroid Build Coastguard Worker domain = "SeRvIcE.arPA.";
233*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSubDomainOf(subDomain, domain));
234*cfb92d14SAndroid Build Coastguard Worker
235*cfb92d14SAndroid Build Coastguard Worker // Verify it doesn't match a portion of a label.
236*cfb92d14SAndroid Build Coastguard Worker subDomain = "my-service._ipps._tcp.default.service.arpa.";
237*cfb92d14SAndroid Build Coastguard Worker domain = "Vice.arpa.";
238*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSubDomainOf(subDomain, domain));
239*cfb92d14SAndroid Build Coastguard Worker
240*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
241*cfb92d14SAndroid Build Coastguard Worker domain2 = "example.com.";
242*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSameDomain(domain, domain2));
243*cfb92d14SAndroid Build Coastguard Worker
244*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
245*cfb92d14SAndroid Build Coastguard Worker domain2 = "example.com";
246*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSameDomain(domain, domain2));
247*cfb92d14SAndroid Build Coastguard Worker
248*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
249*cfb92d14SAndroid Build Coastguard Worker domain2 = "ExAmPlE.cOm";
250*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSameDomain(domain, domain2));
251*cfb92d14SAndroid Build Coastguard Worker
252*cfb92d14SAndroid Build Coastguard Worker domain = "example.com";
253*cfb92d14SAndroid Build Coastguard Worker domain2 = "ExAmPlE.cOm";
254*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSameDomain(domain, domain2));
255*cfb92d14SAndroid Build Coastguard Worker
256*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
257*cfb92d14SAndroid Build Coastguard Worker domain2 = "ExAmPlE.cOm.";
258*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::IsSameDomain(domain, domain2));
259*cfb92d14SAndroid Build Coastguard Worker
260*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
261*cfb92d14SAndroid Build Coastguard Worker domain2 = "aExAmPlE.cOm.";
262*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSameDomain(domain, domain2));
263*cfb92d14SAndroid Build Coastguard Worker
264*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
265*cfb92d14SAndroid Build Coastguard Worker domain2 = "cOm.";
266*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSameDomain(domain, domain2));
267*cfb92d14SAndroid Build Coastguard Worker
268*cfb92d14SAndroid Build Coastguard Worker domain = "example.";
269*cfb92d14SAndroid Build Coastguard Worker domain2 = "example.com.";
270*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSameDomain(domain, domain2));
271*cfb92d14SAndroid Build Coastguard Worker
272*cfb92d14SAndroid Build Coastguard Worker domain = "example.com.";
273*cfb92d14SAndroid Build Coastguard Worker domain2 = ".example.com.";
274*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!Dns::Name::IsSameDomain(domain, domain2));
275*cfb92d14SAndroid Build Coastguard Worker
276*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
277*cfb92d14SAndroid Build Coastguard Worker printf("Extracting label(s) and removing domains:\n");
278*cfb92d14SAndroid Build Coastguard Worker
279*cfb92d14SAndroid Build Coastguard Worker {
280*cfb92d14SAndroid Build Coastguard Worker struct TestCase
281*cfb92d14SAndroid Build Coastguard Worker {
282*cfb92d14SAndroid Build Coastguard Worker const char *mFullName;
283*cfb92d14SAndroid Build Coastguard Worker const char *mSuffixName;
284*cfb92d14SAndroid Build Coastguard Worker const char *mLabels;
285*cfb92d14SAndroid Build Coastguard Worker };
286*cfb92d14SAndroid Build Coastguard Worker
287*cfb92d14SAndroid Build Coastguard Worker static const TestCase kTestCases[] = {
288*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "default.service.arpa.", "my-service._ipps._tcp"},
289*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa", "default.service.arpa", "my-service._ipps._tcp"},
290*cfb92d14SAndroid Build Coastguard Worker {"my.service._ipps._tcp.default.service.arpa.", "_ipps._tcp.default.service.arpa.", "my.service"},
291*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "DeFault.SerVice.ARPA.", "my-service._ipps._tcp"},
292*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa", "DeFault.SerVice.ARPA", "my-service._ipps._tcp"},
293*cfb92d14SAndroid Build Coastguard Worker
294*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa", "default.service.arpa.", nullptr},
295*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "default.service.arpa", nullptr},
296*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "efault.service.arpa.", nullptr},
297*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa", "efault.service.arpa", nullptr},
298*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "xdefault.service.arpa.", nullptr},
299*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", ".default.service.arpa.", nullptr},
300*cfb92d14SAndroid Build Coastguard Worker {"my-service._ipps._tcp.default.service.arpa.", "default.service.arp.", nullptr},
301*cfb92d14SAndroid Build Coastguard Worker {"default.service.arpa.", "default.service.arpa.", nullptr},
302*cfb92d14SAndroid Build Coastguard Worker {"default.service.arpa", "default.service.arpa", nullptr},
303*cfb92d14SAndroid Build Coastguard Worker {"efault.service.arpa.", "default.service.arpa.", nullptr},
304*cfb92d14SAndroid Build Coastguard Worker };
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker for (const TestCase &testCase : kTestCases)
307*cfb92d14SAndroid Build Coastguard Worker {
308*cfb92d14SAndroid Build Coastguard Worker Error error;
309*cfb92d14SAndroid Build Coastguard Worker
310*cfb92d14SAndroid Build Coastguard Worker printf("\n");
311*cfb92d14SAndroid Build Coastguard Worker printf(" FullName : %s\n", testCase.mFullName);
312*cfb92d14SAndroid Build Coastguard Worker printf(" SuffixName : %s\n", testCase.mSuffixName);
313*cfb92d14SAndroid Build Coastguard Worker printf(" Extracted labels: %s\n", (testCase.mLabels != nullptr) ? testCase.mLabels : "(parse)");
314*cfb92d14SAndroid Build Coastguard Worker
315*cfb92d14SAndroid Build Coastguard Worker error = Dns::Name::ExtractLabels(testCase.mFullName, testCase.mSuffixName, name);
316*cfb92d14SAndroid Build Coastguard Worker
317*cfb92d14SAndroid Build Coastguard Worker if (testCase.mLabels != nullptr)
318*cfb92d14SAndroid Build Coastguard Worker {
319*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(error);
320*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, testCase.mLabels) == 0);
321*cfb92d14SAndroid Build Coastguard Worker }
322*cfb92d14SAndroid Build Coastguard Worker else
323*cfb92d14SAndroid Build Coastguard Worker {
324*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorParse);
325*cfb92d14SAndroid Build Coastguard Worker }
326*cfb92d14SAndroid Build Coastguard Worker
327*cfb92d14SAndroid Build Coastguard Worker strcpy(name, testCase.mFullName);
328*cfb92d14SAndroid Build Coastguard Worker error = Dns::Name::StripName(name, testCase.mSuffixName);
329*cfb92d14SAndroid Build Coastguard Worker
330*cfb92d14SAndroid Build Coastguard Worker if (testCase.mLabels != nullptr)
331*cfb92d14SAndroid Build Coastguard Worker {
332*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(error);
333*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, testCase.mLabels) == 0);
334*cfb92d14SAndroid Build Coastguard Worker }
335*cfb92d14SAndroid Build Coastguard Worker else
336*cfb92d14SAndroid Build Coastguard Worker {
337*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorParse);
338*cfb92d14SAndroid Build Coastguard Worker }
339*cfb92d14SAndroid Build Coastguard Worker }
340*cfb92d14SAndroid Build Coastguard Worker
341*cfb92d14SAndroid Build Coastguard Worker fullName = "my-service._ipps._tcp.default.service.arpa.";
342*cfb92d14SAndroid Build Coastguard Worker suffixName = "default.service.arpa.";
343*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 22));
344*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
345*cfb92d14SAndroid Build Coastguard Worker
346*cfb92d14SAndroid Build Coastguard Worker fullName = "my-service._ipps._tcp.default.service.arpa.";
347*cfb92d14SAndroid Build Coastguard Worker suffixName = "default.service.arpa.";
348*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 21) == kErrorNoBufs);
349*cfb92d14SAndroid Build Coastguard Worker }
350*cfb92d14SAndroid Build Coastguard Worker
351*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
352*cfb92d14SAndroid Build Coastguard Worker printf("Append names, check encoded bytes, parse name and read labels:\n");
353*cfb92d14SAndroid Build Coastguard Worker
354*cfb92d14SAndroid Build Coastguard Worker for (const TestName &test : kTestNames)
355*cfb92d14SAndroid Build Coastguard Worker {
356*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
357*cfb92d14SAndroid Build Coastguard Worker
358*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(test.mName, *message));
359*cfb92d14SAndroid Build Coastguard Worker
360*cfb92d14SAndroid Build Coastguard Worker len = message->GetLength();
361*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, buffer, len));
362*cfb92d14SAndroid Build Coastguard Worker
363*cfb92d14SAndroid Build Coastguard Worker DumpBuffer(test.mName, buffer, len);
364*cfb92d14SAndroid Build Coastguard Worker
365*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(len == test.mEncodedLength, "Encoded length does not match expected value");
366*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, test.mEncodedData, len) == 0, "Encoded name data does not match expected data");
367*cfb92d14SAndroid Build Coastguard Worker
368*cfb92d14SAndroid Build Coastguard Worker // Parse and skip over the name
369*cfb92d14SAndroid Build Coastguard Worker offset = 0;
370*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
371*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::ParseName() returned incorrect offset");
372*cfb92d14SAndroid Build Coastguard Worker
373*cfb92d14SAndroid Build Coastguard Worker // Read labels one by one.
374*cfb92d14SAndroid Build Coastguard Worker offset = 0;
375*cfb92d14SAndroid Build Coastguard Worker
376*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; test.mLabels[index] != nullptr; index++)
377*cfb92d14SAndroid Build Coastguard Worker {
378*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
379*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength));
380*cfb92d14SAndroid Build Coastguard Worker
381*cfb92d14SAndroid Build Coastguard Worker printf("Label[%d] = \"%s\"\n", index, label);
382*cfb92d14SAndroid Build Coastguard Worker
383*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, test.mLabels[index]) == 0, "Name::ReadLabel() did not get expected label");
384*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
385*cfb92d14SAndroid Build Coastguard Worker }
386*cfb92d14SAndroid Build Coastguard Worker
387*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
388*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorNotFound,
389*cfb92d14SAndroid Build Coastguard Worker "Name::ReadLabel() failed at end of the name");
390*cfb92d14SAndroid Build Coastguard Worker
391*cfb92d14SAndroid Build Coastguard Worker // Read entire name
392*cfb92d14SAndroid Build Coastguard Worker offset = 0;
393*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
394*cfb92d14SAndroid Build Coastguard Worker
395*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
396*cfb92d14SAndroid Build Coastguard Worker
397*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, test.mExpectedReadName) == 0, "Name::ReadName() did not get expected name");
398*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::ReadName() returned incorrect offset");
399*cfb92d14SAndroid Build Coastguard Worker
400*cfb92d14SAndroid Build Coastguard Worker // Read entire name with different name buffer sizes (just right and one byte off the expected size)
401*cfb92d14SAndroid Build Coastguard Worker offset = 0;
402*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(
403*cfb92d14SAndroid Build Coastguard Worker Dns::Name::ReadName(*message, offset, name, static_cast<uint16_t>(strlen(test.mExpectedReadName) + 1)),
404*cfb92d14SAndroid Build Coastguard Worker "Name::ReadName() failed with exact name buffer size");
405*cfb92d14SAndroid Build Coastguard Worker offset = 0;
406*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadName(*message, offset, name,
407*cfb92d14SAndroid Build Coastguard Worker static_cast<uint16_t>(strlen(test.mExpectedReadName))) == kErrorNoBufs,
408*cfb92d14SAndroid Build Coastguard Worker "Name::ReadName() did not fail with too small name buffer size");
409*cfb92d14SAndroid Build Coastguard Worker
410*cfb92d14SAndroid Build Coastguard Worker // Compare labels one by one.
411*cfb92d14SAndroid Build Coastguard Worker offset = 0;
412*cfb92d14SAndroid Build Coastguard Worker
413*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; test.mLabels[index] != nullptr; index++)
414*cfb92d14SAndroid Build Coastguard Worker {
415*cfb92d14SAndroid Build Coastguard Worker uint16_t startOffset = offset;
416*cfb92d14SAndroid Build Coastguard Worker
417*cfb92d14SAndroid Build Coastguard Worker strcpy(label, test.mLabels[index]);
418*cfb92d14SAndroid Build Coastguard Worker
419*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, label));
420*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset != startOffset, "Name::CompareLabel() did not change offset");
421*cfb92d14SAndroid Build Coastguard Worker
422*cfb92d14SAndroid Build Coastguard Worker offset = startOffset;
423*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareLabel(*message, offset, kBadLabel) == kErrorNotFound,
424*cfb92d14SAndroid Build Coastguard Worker "Name::CompareLabel() did not fail with incorrect label");
425*cfb92d14SAndroid Build Coastguard Worker
426*cfb92d14SAndroid Build Coastguard Worker StringConvertToUppercase(label);
427*cfb92d14SAndroid Build Coastguard Worker
428*cfb92d14SAndroid Build Coastguard Worker offset = startOffset;
429*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, label));
430*cfb92d14SAndroid Build Coastguard Worker }
431*cfb92d14SAndroid Build Coastguard Worker
432*cfb92d14SAndroid Build Coastguard Worker // Compare the whole name.
433*cfb92d14SAndroid Build Coastguard Worker strcpy(name, test.mExpectedReadName);
434*cfb92d14SAndroid Build Coastguard Worker
435*cfb92d14SAndroid Build Coastguard Worker offset = 0;
436*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, name));
437*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::CompareName() returned incorrect offset");
438*cfb92d14SAndroid Build Coastguard Worker
439*cfb92d14SAndroid Build Coastguard Worker StringConvertToUppercase(name);
440*cfb92d14SAndroid Build Coastguard Worker
441*cfb92d14SAndroid Build Coastguard Worker offset = 0;
442*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, name));
443*cfb92d14SAndroid Build Coastguard Worker
444*cfb92d14SAndroid Build Coastguard Worker offset = 0;
445*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, kBadName) == kErrorNotFound,
446*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with incorrect name");
447*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::CompareName() returned incorrect offset");
448*cfb92d14SAndroid Build Coastguard Worker
449*cfb92d14SAndroid Build Coastguard Worker // Remove the terminating '.' in expected name and verify
450*cfb92d14SAndroid Build Coastguard Worker // that it can still be used by `CompareName()`.
451*cfb92d14SAndroid Build Coastguard Worker offset = 0;
452*cfb92d14SAndroid Build Coastguard Worker strcpy(name, test.mExpectedReadName);
453*cfb92d14SAndroid Build Coastguard Worker name[strlen(name) - 1] = '\0';
454*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, name));
455*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::CompareName() returned incorrect offset");
456*cfb92d14SAndroid Build Coastguard Worker
457*cfb92d14SAndroid Build Coastguard Worker if (strlen(name) >= 1)
458*cfb92d14SAndroid Build Coastguard Worker {
459*cfb92d14SAndroid Build Coastguard Worker name[strlen(name) - 1] = '\0';
460*cfb92d14SAndroid Build Coastguard Worker offset = 0;
461*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, name) == kErrorNotFound,
462*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with invalid name");
463*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::CompareName() returned incorrect offset");
464*cfb92d14SAndroid Build Coastguard Worker }
465*cfb92d14SAndroid Build Coastguard Worker
466*cfb92d14SAndroid Build Coastguard Worker // Compare the name with itself read from message.
467*cfb92d14SAndroid Build Coastguard Worker offset = 0;
468*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, *message, offset));
469*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == len, "Name::CompareName() returned incorrect offset");
470*cfb92d14SAndroid Build Coastguard Worker }
471*cfb92d14SAndroid Build Coastguard Worker
472*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
473*cfb92d14SAndroid Build Coastguard Worker printf("Max length names:\n");
474*cfb92d14SAndroid Build Coastguard Worker
475*cfb92d14SAndroid Build Coastguard Worker for (const char *&maxLengthName : kMaxLengthNames)
476*cfb92d14SAndroid Build Coastguard Worker {
477*cfb92d14SAndroid Build Coastguard Worker if (maxLengthName[strlen(maxLengthName) - 1] == '.')
478*cfb92d14SAndroid Build Coastguard Worker {
479*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strlen(maxLengthName) == kMaxNameLength);
480*cfb92d14SAndroid Build Coastguard Worker }
481*cfb92d14SAndroid Build Coastguard Worker else
482*cfb92d14SAndroid Build Coastguard Worker {
483*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strlen(maxLengthName) == kMaxNameLength - 1);
484*cfb92d14SAndroid Build Coastguard Worker }
485*cfb92d14SAndroid Build Coastguard Worker
486*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
487*cfb92d14SAndroid Build Coastguard Worker
488*cfb92d14SAndroid Build Coastguard Worker printf("\"%s\"\n", maxLengthName);
489*cfb92d14SAndroid Build Coastguard Worker
490*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(maxLengthName, *message));
491*cfb92d14SAndroid Build Coastguard Worker }
492*cfb92d14SAndroid Build Coastguard Worker
493*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
494*cfb92d14SAndroid Build Coastguard Worker printf("Invalid names:\n");
495*cfb92d14SAndroid Build Coastguard Worker
496*cfb92d14SAndroid Build Coastguard Worker for (const char *&invalidName : kInvalidNames)
497*cfb92d14SAndroid Build Coastguard Worker {
498*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
499*cfb92d14SAndroid Build Coastguard Worker
500*cfb92d14SAndroid Build Coastguard Worker printf("\"%s\"\n", invalidName);
501*cfb92d14SAndroid Build Coastguard Worker
502*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::AppendName(invalidName, *message) == kErrorInvalidArgs);
503*cfb92d14SAndroid Build Coastguard Worker }
504*cfb92d14SAndroid Build Coastguard Worker
505*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
506*cfb92d14SAndroid Build Coastguard Worker printf("Append as multiple labels and terminator instead of full name:\n");
507*cfb92d14SAndroid Build Coastguard Worker
508*cfb92d14SAndroid Build Coastguard Worker for (const TestName &test : kTestNames)
509*cfb92d14SAndroid Build Coastguard Worker {
510*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
511*cfb92d14SAndroid Build Coastguard Worker
512*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendMultipleLabels(test.mName, *message));
513*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendTerminator(*message));
514*cfb92d14SAndroid Build Coastguard Worker
515*cfb92d14SAndroid Build Coastguard Worker len = message->GetLength();
516*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, buffer, len));
517*cfb92d14SAndroid Build Coastguard Worker
518*cfb92d14SAndroid Build Coastguard Worker DumpBuffer(test.mName, buffer, len);
519*cfb92d14SAndroid Build Coastguard Worker
520*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(len == test.mEncodedLength, "Encoded length does not match expected value");
521*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, test.mEncodedData, len) == 0, "Encoded name data does not match expected data");
522*cfb92d14SAndroid Build Coastguard Worker }
523*cfb92d14SAndroid Build Coastguard Worker
524*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
525*cfb92d14SAndroid Build Coastguard Worker printf("Append labels one by one:\n");
526*cfb92d14SAndroid Build Coastguard Worker
527*cfb92d14SAndroid Build Coastguard Worker for (const TestName &test : kTestNames)
528*cfb92d14SAndroid Build Coastguard Worker {
529*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
530*cfb92d14SAndroid Build Coastguard Worker
531*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; test.mLabels[index] != nullptr; index++)
532*cfb92d14SAndroid Build Coastguard Worker {
533*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendLabel(test.mLabels[index], *message));
534*cfb92d14SAndroid Build Coastguard Worker }
535*cfb92d14SAndroid Build Coastguard Worker
536*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendTerminator(*message));
537*cfb92d14SAndroid Build Coastguard Worker
538*cfb92d14SAndroid Build Coastguard Worker len = message->GetLength();
539*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, buffer, len));
540*cfb92d14SAndroid Build Coastguard Worker
541*cfb92d14SAndroid Build Coastguard Worker DumpBuffer(test.mName, buffer, len);
542*cfb92d14SAndroid Build Coastguard Worker
543*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(len == test.mEncodedLength, "Encoded length does not match expected value");
544*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, test.mEncodedData, len) == 0, "Encoded name data does not match expected data");
545*cfb92d14SAndroid Build Coastguard Worker }
546*cfb92d14SAndroid Build Coastguard Worker
547*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
548*cfb92d14SAndroid Build Coastguard Worker printf("Name::Matches() variations\n");
549*cfb92d14SAndroid Build Coastguard Worker
550*cfb92d14SAndroid Build Coastguard Worker for (const TestMatches &test : kTestMatches)
551*cfb92d14SAndroid Build Coastguard Worker {
552*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\"\n", test.mFullName);
553*cfb92d14SAndroid Build Coastguard Worker
554*cfb92d14SAndroid Build Coastguard Worker dnsName.Set(test.mFullName);
555*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches(test.mFirstLabel, test.mLabels, test.mDomain) == test.mShouldMatch);
556*cfb92d14SAndroid Build Coastguard Worker
557*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
558*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(dnsName.AppendTo(*message));
559*cfb92d14SAndroid Build Coastguard Worker
560*cfb92d14SAndroid Build Coastguard Worker dnsName.SetFromMessage(*message, 0);
561*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches(test.mFirstLabel, test.mLabels, test.mDomain) == test.mShouldMatch);
562*cfb92d14SAndroid Build Coastguard Worker }
563*cfb92d14SAndroid Build Coastguard Worker
564*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(0));
565*cfb92d14SAndroid Build Coastguard Worker dnsName.SetFromMessage(*message, 0);
566*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendLabel("Name.With.Dot", *message));
567*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName("_srv._udp.local.", *message));
568*cfb92d14SAndroid Build Coastguard Worker
569*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("Name.With.Dot", "_srv._udp", "local."));
570*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("nAme.with.dOT", "_srv._udp", "local."));
571*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("Name.With.Dot", "_srv", "_udp.local."));
572*cfb92d14SAndroid Build Coastguard Worker
573*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name", "With.Dot._srv._udp", "local."));
574*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.", "With.Dot._srv._udp", "local."));
575*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With", "Dot._srv._udp", "local."));
576*cfb92d14SAndroid Build Coastguard Worker
577*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dott", "_srv._udp", "local."));
578*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot.", "_srv._udp", "local."));
579*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot", "_srv._tcp", "local."));
580*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot", "_srv._udp", "arpa."));
581*cfb92d14SAndroid Build Coastguard Worker
582*cfb92d14SAndroid Build Coastguard Worker offset = 0;
583*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
584*cfb92d14SAndroid Build Coastguard Worker dnsName.Set(name);
585*cfb92d14SAndroid Build Coastguard Worker
586*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("Name.With.Dot", "_srv._udp", "local."));
587*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("nAme.with.dOT", "_srv._udp", "local."));
588*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(dnsName.Matches("Name.With.Dot", "_srv", "_udp.local."));
589*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dott", "_srv._udp", "local."));
590*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot.", "_srv._udp", "local."));
591*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot", "_srv._tcp", "local."));
592*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!dnsName.Matches("Name.With.Dot", "_srv._udp", "arpa."));
593*cfb92d14SAndroid Build Coastguard Worker
594*cfb92d14SAndroid Build Coastguard Worker message->Free();
595*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
596*cfb92d14SAndroid Build Coastguard Worker }
597*cfb92d14SAndroid Build Coastguard Worker
TestDnsCompressedName(void)598*cfb92d14SAndroid Build Coastguard Worker void TestDnsCompressedName(void)
599*cfb92d14SAndroid Build Coastguard Worker {
600*cfb92d14SAndroid Build Coastguard Worker enum
601*cfb92d14SAndroid Build Coastguard Worker {
602*cfb92d14SAndroid Build Coastguard Worker kHeaderOffset = 10,
603*cfb92d14SAndroid Build Coastguard Worker kGuardBlockSize = 20,
604*cfb92d14SAndroid Build Coastguard Worker kMaxBufferSize = 100,
605*cfb92d14SAndroid Build Coastguard Worker kLabelSize = 64,
606*cfb92d14SAndroid Build Coastguard Worker kNameSize = 256,
607*cfb92d14SAndroid Build Coastguard Worker
608*cfb92d14SAndroid Build Coastguard Worker kName2EncodedSize = 4 + 2, // encoded "FOO" + pointer label (2 bytes)
609*cfb92d14SAndroid Build Coastguard Worker kName3EncodedSize = 2, // pointer label (2 bytes)
610*cfb92d14SAndroid Build Coastguard Worker kName4EncodedSize = 15 + 2, // encoded "Human.Readable" + pointer label (2 bytes).
611*cfb92d14SAndroid Build Coastguard Worker
612*cfb92d14SAndroid Build Coastguard Worker };
613*cfb92d14SAndroid Build Coastguard Worker
614*cfb92d14SAndroid Build Coastguard Worker const char kName[] = "F.ISI.ARPA";
615*cfb92d14SAndroid Build Coastguard Worker const char kLabel1[] = "FOO";
616*cfb92d14SAndroid Build Coastguard Worker const char kInstanceLabel[] = "Human.Readable";
617*cfb92d14SAndroid Build Coastguard Worker
618*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {1, 'F', 3, 'I', 'S', 'I', 4, 'A', 'R', 'P', 'A', 0};
619*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kIsiRelativeIndex = 2; // Index in kEncodedName to the start of "ISI.ARPA" portion.
620*cfb92d14SAndroid Build Coastguard Worker
621*cfb92d14SAndroid Build Coastguard Worker static const char *kName1Labels[] = {"F", "ISI", "ARPA"};
622*cfb92d14SAndroid Build Coastguard Worker static const char *kName2Labels[] = {"FOO", "F", "ISI", "ARPA"};
623*cfb92d14SAndroid Build Coastguard Worker static const char *kName3Labels[] = {"ISI", "ARPA"};
624*cfb92d14SAndroid Build Coastguard Worker static const char *kName4Labels[] = {"Human.Readable", "F", "ISI", "ARPA"};
625*cfb92d14SAndroid Build Coastguard Worker
626*cfb92d14SAndroid Build Coastguard Worker static const char *kName1MultiLabels[] = {"F.ISI", "ARPA"};
627*cfb92d14SAndroid Build Coastguard Worker static const char *kName2MultiLabels1[] = {"FOO", "F.ISI.ARPA."};
628*cfb92d14SAndroid Build Coastguard Worker static const char *kName2MultiLabels2[] = {"FOO.F.", "ISI.ARPA."};
629*cfb92d14SAndroid Build Coastguard Worker
630*cfb92d14SAndroid Build Coastguard Worker static const char kName1BadMultiLabels[] = "F.ISI.ARPA.MORE";
631*cfb92d14SAndroid Build Coastguard Worker static const char kName2BadMultiLabels[] = "FOO.F.IS";
632*cfb92d14SAndroid Build Coastguard Worker
633*cfb92d14SAndroid Build Coastguard Worker static const char kExpectedReadName1[] = "F.ISI.ARPA.";
634*cfb92d14SAndroid Build Coastguard Worker static const char kExpectedReadName2[] = "FOO.F.ISI.ARPA.";
635*cfb92d14SAndroid Build Coastguard Worker static const char kExpectedReadName3[] = "ISI.ARPA.";
636*cfb92d14SAndroid Build Coastguard Worker static const char kExpectedReadName4[] = "Human.Readable.F.ISI.ARPA.";
637*cfb92d14SAndroid Build Coastguard Worker
638*cfb92d14SAndroid Build Coastguard Worker static const char kBadName[] = "bad.name";
639*cfb92d14SAndroid Build Coastguard Worker
640*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
641*cfb92d14SAndroid Build Coastguard Worker MessagePool *messagePool;
642*cfb92d14SAndroid Build Coastguard Worker Message *message;
643*cfb92d14SAndroid Build Coastguard Worker Message *message2;
644*cfb92d14SAndroid Build Coastguard Worker uint16_t offset;
645*cfb92d14SAndroid Build Coastguard Worker uint16_t name1Offset;
646*cfb92d14SAndroid Build Coastguard Worker uint16_t name2Offset;
647*cfb92d14SAndroid Build Coastguard Worker uint16_t name3Offset;
648*cfb92d14SAndroid Build Coastguard Worker uint16_t name4Offset;
649*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxBufferSize];
650*cfb92d14SAndroid Build Coastguard Worker char label[kLabelSize];
651*cfb92d14SAndroid Build Coastguard Worker uint8_t labelLength;
652*cfb92d14SAndroid Build Coastguard Worker char name[kNameSize];
653*cfb92d14SAndroid Build Coastguard Worker Dns::Name dnsName1;
654*cfb92d14SAndroid Build Coastguard Worker Dns::Name dnsName2;
655*cfb92d14SAndroid Build Coastguard Worker Dns::Name dnsName3;
656*cfb92d14SAndroid Build Coastguard Worker Dns::Name dnsName4;
657*cfb92d14SAndroid Build Coastguard Worker
658*cfb92d14SAndroid Build Coastguard Worker printf("================================================================\n");
659*cfb92d14SAndroid Build Coastguard Worker printf("TestDnsCompressedName()\n");
660*cfb92d14SAndroid Build Coastguard Worker
661*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
662*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
663*cfb92d14SAndroid Build Coastguard Worker
664*cfb92d14SAndroid Build Coastguard Worker messagePool = &instance->Get<MessagePool>();
665*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
666*cfb92d14SAndroid Build Coastguard Worker
667*cfb92d14SAndroid Build Coastguard Worker // Append name1 "F.ISI.ARPA"
668*cfb92d14SAndroid Build Coastguard Worker
669*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; index < kHeaderOffset + kGuardBlockSize; index++)
670*cfb92d14SAndroid Build Coastguard Worker {
671*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(index));
672*cfb92d14SAndroid Build Coastguard Worker }
673*cfb92d14SAndroid Build Coastguard Worker
674*cfb92d14SAndroid Build Coastguard Worker message->SetOffset(kHeaderOffset);
675*cfb92d14SAndroid Build Coastguard Worker
676*cfb92d14SAndroid Build Coastguard Worker name1Offset = message->GetLength();
677*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(kName, *message));
678*cfb92d14SAndroid Build Coastguard Worker
679*cfb92d14SAndroid Build Coastguard Worker // Append name2 "FOO.F.ISI.ARPA" as a compressed name after some guard/extra bytes
680*cfb92d14SAndroid Build Coastguard Worker
681*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; index < kGuardBlockSize; index++)
682*cfb92d14SAndroid Build Coastguard Worker {
683*cfb92d14SAndroid Build Coastguard Worker uint8_t value = 0xff;
684*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(value));
685*cfb92d14SAndroid Build Coastguard Worker }
686*cfb92d14SAndroid Build Coastguard Worker
687*cfb92d14SAndroid Build Coastguard Worker name2Offset = message->GetLength();
688*cfb92d14SAndroid Build Coastguard Worker
689*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendLabel(kLabel1, *message));
690*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(name1Offset - kHeaderOffset, *message));
691*cfb92d14SAndroid Build Coastguard Worker
692*cfb92d14SAndroid Build Coastguard Worker // Append name3 "ISI.ARPA" as a compressed name after some guard/extra bytes
693*cfb92d14SAndroid Build Coastguard Worker
694*cfb92d14SAndroid Build Coastguard Worker for (uint8_t index = 0; index < kGuardBlockSize; index++)
695*cfb92d14SAndroid Build Coastguard Worker {
696*cfb92d14SAndroid Build Coastguard Worker uint8_t value = 0xaa;
697*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(value));
698*cfb92d14SAndroid Build Coastguard Worker }
699*cfb92d14SAndroid Build Coastguard Worker
700*cfb92d14SAndroid Build Coastguard Worker name3Offset = message->GetLength();
701*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(name1Offset + kIsiRelativeIndex - kHeaderOffset, *message));
702*cfb92d14SAndroid Build Coastguard Worker
703*cfb92d14SAndroid Build Coastguard Worker name4Offset = message->GetLength();
704*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendLabel(kInstanceLabel, *message));
705*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(name1Offset - kHeaderOffset, *message));
706*cfb92d14SAndroid Build Coastguard Worker
707*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
708*cfb92d14SAndroid Build Coastguard Worker printf("Read and parse the uncompressed name-1 \"F.ISI.ARPA\"\n");
709*cfb92d14SAndroid Build Coastguard Worker
710*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(name1Offset, buffer, sizeof(kEncodedName)));
711*cfb92d14SAndroid Build Coastguard Worker
712*cfb92d14SAndroid Build Coastguard Worker DumpBuffer(kName, buffer, sizeof(kEncodedName));
713*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kEncodedName, sizeof(kEncodedName)) == 0,
714*cfb92d14SAndroid Build Coastguard Worker "Encoded name data does not match expected data");
715*cfb92d14SAndroid Build Coastguard Worker
716*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
717*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
718*cfb92d14SAndroid Build Coastguard Worker
719*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::ParseName() returned incorrect offset");
720*cfb92d14SAndroid Build Coastguard Worker
721*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
722*cfb92d14SAndroid Build Coastguard Worker
723*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName1Labels)
724*cfb92d14SAndroid Build Coastguard Worker {
725*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
726*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength));
727*cfb92d14SAndroid Build Coastguard Worker
728*cfb92d14SAndroid Build Coastguard Worker printf("label: \"%s\"\n", label);
729*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, nameLabel) == 0, "Name::ReadLabel() did not get expected label");
730*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
731*cfb92d14SAndroid Build Coastguard Worker }
732*cfb92d14SAndroid Build Coastguard Worker
733*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
734*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorNotFound,
735*cfb92d14SAndroid Build Coastguard Worker "Name::ReadLabel() failed at end of the name");
736*cfb92d14SAndroid Build Coastguard Worker
737*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
738*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
739*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
740*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kExpectedReadName1) == 0, "Name::ReadName() did not return expected name");
741*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::ReadName() returned incorrect offset");
742*cfb92d14SAndroid Build Coastguard Worker
743*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
744*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName1Labels)
745*cfb92d14SAndroid Build Coastguard Worker {
746*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, nameLabel));
747*cfb92d14SAndroid Build Coastguard Worker }
748*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
749*cfb92d14SAndroid Build Coastguard Worker
750*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
751*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName1Labels)
752*cfb92d14SAndroid Build Coastguard Worker {
753*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabel));
754*cfb92d14SAndroid Build Coastguard Worker }
755*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
756*cfb92d14SAndroid Build Coastguard Worker
757*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
758*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kExpectedReadName1));
759*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
760*cfb92d14SAndroid Build Coastguard Worker
761*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
762*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kBadName) == kErrorNotFound);
763*cfb92d14SAndroid Build Coastguard Worker
764*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
765*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kName1BadMultiLabels) == kErrorNotFound);
766*cfb92d14SAndroid Build Coastguard Worker
767*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
768*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabels : kName1MultiLabels)
769*cfb92d14SAndroid Build Coastguard Worker {
770*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabels));
771*cfb92d14SAndroid Build Coastguard Worker }
772*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
773*cfb92d14SAndroid Build Coastguard Worker
774*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
775*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kExpectedReadName1));
776*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::CompareName() returned incorrect offset");
777*cfb92d14SAndroid Build Coastguard Worker
778*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
779*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, kBadName) == kErrorNotFound,
780*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with incorrect name");
781*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::CompareName() returned incorrect offset");
782*cfb92d14SAndroid Build Coastguard Worker
783*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
784*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, *message, offset));
785*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::CompareName() returned incorrect offset");
786*cfb92d14SAndroid Build Coastguard Worker
787*cfb92d14SAndroid Build Coastguard Worker offset = name1Offset;
788*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, *message, name2Offset) == kErrorNotFound,
789*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with mismatching name");
790*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name1Offset + sizeof(kEncodedName), "Name::CompareName() returned incorrect offset");
791*cfb92d14SAndroid Build Coastguard Worker
792*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
793*cfb92d14SAndroid Build Coastguard Worker printf("Read and parse compressed name-2 \"FOO.F.ISI.ARPA\"\n");
794*cfb92d14SAndroid Build Coastguard Worker
795*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(name2Offset, buffer, kName2EncodedSize));
796*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("name2(compressed)", buffer, kName2EncodedSize);
797*cfb92d14SAndroid Build Coastguard Worker
798*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
799*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
800*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::ParseName() returned incorrect offset");
801*cfb92d14SAndroid Build Coastguard Worker
802*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
803*cfb92d14SAndroid Build Coastguard Worker
804*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName2Labels)
805*cfb92d14SAndroid Build Coastguard Worker {
806*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
807*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength));
808*cfb92d14SAndroid Build Coastguard Worker
809*cfb92d14SAndroid Build Coastguard Worker printf("label: \"%s\"\n", label);
810*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, nameLabel) == 0, "Name::ReadLabel() did not get expected label");
811*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
812*cfb92d14SAndroid Build Coastguard Worker }
813*cfb92d14SAndroid Build Coastguard Worker
814*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
815*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorNotFound,
816*cfb92d14SAndroid Build Coastguard Worker "Name::ReadLabel() failed at end of the name");
817*cfb92d14SAndroid Build Coastguard Worker
818*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
819*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
820*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
821*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kExpectedReadName2) == 0, "Name::ReadName() did not return expected name");
822*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::ReadName() returned incorrect offset");
823*cfb92d14SAndroid Build Coastguard Worker
824*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
825*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName2Labels)
826*cfb92d14SAndroid Build Coastguard Worker {
827*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, nameLabel));
828*cfb92d14SAndroid Build Coastguard Worker }
829*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
830*cfb92d14SAndroid Build Coastguard Worker
831*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
832*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName2Labels)
833*cfb92d14SAndroid Build Coastguard Worker {
834*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabel));
835*cfb92d14SAndroid Build Coastguard Worker }
836*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
837*cfb92d14SAndroid Build Coastguard Worker
838*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
839*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kExpectedReadName2));
840*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
841*cfb92d14SAndroid Build Coastguard Worker
842*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
843*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kBadName) == kErrorNotFound);
844*cfb92d14SAndroid Build Coastguard Worker
845*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
846*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kName2BadMultiLabels) == kErrorNotFound);
847*cfb92d14SAndroid Build Coastguard Worker
848*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
849*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabels : kName2MultiLabels1)
850*cfb92d14SAndroid Build Coastguard Worker {
851*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabels));
852*cfb92d14SAndroid Build Coastguard Worker }
853*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
854*cfb92d14SAndroid Build Coastguard Worker
855*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
856*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabels : kName2MultiLabels2)
857*cfb92d14SAndroid Build Coastguard Worker {
858*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabels));
859*cfb92d14SAndroid Build Coastguard Worker }
860*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
861*cfb92d14SAndroid Build Coastguard Worker
862*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
863*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kExpectedReadName2));
864*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::CompareName() returned incorrect offset");
865*cfb92d14SAndroid Build Coastguard Worker
866*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
867*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, kBadName) == kErrorNotFound,
868*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with incorrect name");
869*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::CompareName() returned incorrect offset");
870*cfb92d14SAndroid Build Coastguard Worker
871*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
872*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, *message, offset), "Name::CompareName() with itself failed");
873*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::CompareName() returned incorrect offset");
874*cfb92d14SAndroid Build Coastguard Worker
875*cfb92d14SAndroid Build Coastguard Worker offset = name2Offset;
876*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, *message, name3Offset) == kErrorNotFound,
877*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with mismatching name");
878*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name2Offset + kName2EncodedSize, "Name::CompareName() returned incorrect offset");
879*cfb92d14SAndroid Build Coastguard Worker
880*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
881*cfb92d14SAndroid Build Coastguard Worker printf("Read and parse compressed name-3 \"ISI.ARPA\"\n");
882*cfb92d14SAndroid Build Coastguard Worker
883*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(name3Offset, buffer, kName3EncodedSize));
884*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("name2(compressed)", buffer, kName3EncodedSize);
885*cfb92d14SAndroid Build Coastguard Worker
886*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
887*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
888*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::ParseName() returned incorrect offset");
889*cfb92d14SAndroid Build Coastguard Worker
890*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
891*cfb92d14SAndroid Build Coastguard Worker
892*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName3Labels)
893*cfb92d14SAndroid Build Coastguard Worker {
894*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
895*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength));
896*cfb92d14SAndroid Build Coastguard Worker
897*cfb92d14SAndroid Build Coastguard Worker printf("label: \"%s\"\n", label);
898*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, nameLabel) == 0, "Name::ReadLabel() did not get expected label");
899*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
900*cfb92d14SAndroid Build Coastguard Worker }
901*cfb92d14SAndroid Build Coastguard Worker
902*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
903*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorNotFound,
904*cfb92d14SAndroid Build Coastguard Worker "Name::ReadLabel() failed at end of the name");
905*cfb92d14SAndroid Build Coastguard Worker
906*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
907*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
908*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
909*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kExpectedReadName3) == 0, "Name::ReadName() did not return expected name");
910*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::ReadName() returned incorrect offset");
911*cfb92d14SAndroid Build Coastguard Worker
912*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
913*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName3Labels)
914*cfb92d14SAndroid Build Coastguard Worker {
915*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, nameLabel));
916*cfb92d14SAndroid Build Coastguard Worker }
917*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
918*cfb92d14SAndroid Build Coastguard Worker
919*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
920*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName3Labels)
921*cfb92d14SAndroid Build Coastguard Worker {
922*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabel));
923*cfb92d14SAndroid Build Coastguard Worker }
924*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
925*cfb92d14SAndroid Build Coastguard Worker
926*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
927*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, kExpectedReadName3));
928*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
929*cfb92d14SAndroid Build Coastguard Worker
930*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
931*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kExpectedReadName3));
932*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::CompareName() returned incorrect offset");
933*cfb92d14SAndroid Build Coastguard Worker
934*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
935*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, kBadName) == kErrorNotFound,
936*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with incorrect name");
937*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::CompareName() returned incorrect offset");
938*cfb92d14SAndroid Build Coastguard Worker
939*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
940*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, *message, offset), "Name::CompareName() with itself failed");
941*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::CompareName() returned incorrect offset");
942*cfb92d14SAndroid Build Coastguard Worker
943*cfb92d14SAndroid Build Coastguard Worker offset = name3Offset;
944*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, *message, name4Offset) == kErrorNotFound,
945*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with mismatching name");
946*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name3Offset + kName3EncodedSize, "Name::CompareName() returned incorrect offset");
947*cfb92d14SAndroid Build Coastguard Worker
948*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
949*cfb92d14SAndroid Build Coastguard Worker printf("Read and parse the uncompressed name-4 \"Human\\.Readable.F.ISI.ARPA\"\n");
950*cfb92d14SAndroid Build Coastguard Worker
951*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(name4Offset, buffer, kName4EncodedSize));
952*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("name4(compressed)", buffer, kName4EncodedSize);
953*cfb92d14SAndroid Build Coastguard Worker
954*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
955*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
956*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name4Offset + kName4EncodedSize, "Name::ParseName() returned incorrect offset");
957*cfb92d14SAndroid Build Coastguard Worker
958*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
959*cfb92d14SAndroid Build Coastguard Worker
960*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName4Labels)
961*cfb92d14SAndroid Build Coastguard Worker {
962*cfb92d14SAndroid Build Coastguard Worker labelLength = sizeof(label);
963*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength));
964*cfb92d14SAndroid Build Coastguard Worker
965*cfb92d14SAndroid Build Coastguard Worker printf("label: \"%s\"\n", label);
966*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, nameLabel) == 0, "Name::ReadLabel() did not get expected label");
967*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
968*cfb92d14SAndroid Build Coastguard Worker }
969*cfb92d14SAndroid Build Coastguard Worker
970*cfb92d14SAndroid Build Coastguard Worker // `ReadName()` for name-4 should still succeed since only the first label contains dot char
971*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
972*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
973*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
974*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kExpectedReadName4) == 0, "Name::ReadName() did not return expected name");
975*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == name4Offset + kName4EncodedSize, "Name::ParseName() returned incorrect offset");
976*cfb92d14SAndroid Build Coastguard Worker
977*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
978*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName4Labels)
979*cfb92d14SAndroid Build Coastguard Worker {
980*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareLabel(*message, offset, nameLabel));
981*cfb92d14SAndroid Build Coastguard Worker }
982*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
983*cfb92d14SAndroid Build Coastguard Worker
984*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
985*cfb92d14SAndroid Build Coastguard Worker for (const char *nameLabel : kName4Labels)
986*cfb92d14SAndroid Build Coastguard Worker {
987*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareMultipleLabels(*message, offset, nameLabel));
988*cfb92d14SAndroid Build Coastguard Worker }
989*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, "."));
990*cfb92d14SAndroid Build Coastguard Worker
991*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
992*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, *message, offset), "Name::CompareName() with itself failed");
993*cfb92d14SAndroid Build Coastguard Worker
994*cfb92d14SAndroid Build Coastguard Worker offset = name4Offset;
995*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, *message, name1Offset) == kErrorNotFound,
996*cfb92d14SAndroid Build Coastguard Worker "Name::CompareName() did not fail with mismatching name");
997*cfb92d14SAndroid Build Coastguard Worker
998*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
999*cfb92d14SAndroid Build Coastguard Worker printf("Append names from one message to another\n");
1000*cfb92d14SAndroid Build Coastguard Worker
1001*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message2 = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
1002*cfb92d14SAndroid Build Coastguard Worker
1003*cfb92d14SAndroid Build Coastguard Worker dnsName1.SetFromMessage(*message, name1Offset);
1004*cfb92d14SAndroid Build Coastguard Worker dnsName2.SetFromMessage(*message, name2Offset);
1005*cfb92d14SAndroid Build Coastguard Worker dnsName3.SetFromMessage(*message, name3Offset);
1006*cfb92d14SAndroid Build Coastguard Worker dnsName4.SetFromMessage(*message, name4Offset);
1007*cfb92d14SAndroid Build Coastguard Worker
1008*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1009*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(dnsName1.AppendTo(*message2));
1010*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(dnsName2.AppendTo(*message2));
1011*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(dnsName3.AppendTo(*message2));
1012*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(dnsName4.AppendTo(*message2));
1013*cfb92d14SAndroid Build Coastguard Worker
1014*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message2->Read(0, buffer, message2->GetLength()));
1015*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("message2", buffer, message2->GetLength());
1016*cfb92d14SAndroid Build Coastguard Worker
1017*cfb92d14SAndroid Build Coastguard Worker // Now compare the names one by one in `message2`. Note that
1018*cfb92d14SAndroid Build Coastguard Worker // `CompareName()` will update `offset` on success.
1019*cfb92d14SAndroid Build Coastguard Worker
1020*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message2, offset, dnsName1));
1021*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message2, offset, dnsName2));
1022*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message2, offset, dnsName3));
1023*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message2, offset, dnsName4));
1024*cfb92d14SAndroid Build Coastguard Worker
1025*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1026*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message2, offset, name));
1027*cfb92d14SAndroid Build Coastguard Worker printf("- Name1 after `AppendTo()`: \"%s\"\n", name);
1028*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message2, offset, name));
1029*cfb92d14SAndroid Build Coastguard Worker printf("- Name2 after `AppendTo()`: \"%s\"\n", name);
1030*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message2, offset, name));
1031*cfb92d14SAndroid Build Coastguard Worker printf("- Name3 after `AppendTo()`: \"%s\"\n", name);
1032*cfb92d14SAndroid Build Coastguard Worker // `ReadName()` for name-4 will fail due to first label containing dot char.
1033*cfb92d14SAndroid Build Coastguard Worker
1034*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
1035*cfb92d14SAndroid Build Coastguard Worker printf("Improperly formatted names (looped)\n");
1036*cfb92d14SAndroid Build Coastguard Worker
1037*cfb92d14SAndroid Build Coastguard Worker {
1038*cfb92d14SAndroid Build Coastguard Worker // Pointer label jumps forward to offset 6.
1039*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {3, 'F', 'O', 'O', 0xc0, 6, 2, 'A', 'B', 0};
1040*cfb92d14SAndroid Build Coastguard Worker
1041*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1042*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kEncodedName));
1043*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("pointer-moving-forward", kEncodedName, sizeof(kEncodedName));
1044*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1045*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ParseName(*message, offset) == kErrorParse);
1046*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadName(*message, offset, name) == kErrorParse);
1047*cfb92d14SAndroid Build Coastguard Worker }
1048*cfb92d14SAndroid Build Coastguard Worker
1049*cfb92d14SAndroid Build Coastguard Worker {
1050*cfb92d14SAndroid Build Coastguard Worker // Pointer label jumps back to offset 0 creating a loop.
1051*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {0xc0, 0};
1052*cfb92d14SAndroid Build Coastguard Worker
1053*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1054*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kEncodedName));
1055*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("looped-name", kEncodedName, sizeof(kEncodedName));
1056*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1057*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ParseName(*message, offset) == kErrorParse);
1058*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadName(*message, offset, name) == kErrorParse);
1059*cfb92d14SAndroid Build Coastguard Worker }
1060*cfb92d14SAndroid Build Coastguard Worker
1061*cfb92d14SAndroid Build Coastguard Worker {
1062*cfb92d14SAndroid Build Coastguard Worker // After first label, we have a pointer label jumping back to
1063*cfb92d14SAndroid Build Coastguard Worker // offset 0, creating a loop.
1064*cfb92d14SAndroid Build Coastguard Worker
1065*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {3, 'F', 'O', 'O', 0xc0, 0};
1066*cfb92d14SAndroid Build Coastguard Worker
1067*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1068*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kEncodedName));
1069*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("looped-one-label", kEncodedName, sizeof(kEncodedName));
1070*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1071*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ParseName(*message, offset) == kErrorParse);
1072*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadName(*message, offset, name) == kErrorParse);
1073*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, "FOO.") == kErrorParse);
1074*cfb92d14SAndroid Build Coastguard Worker }
1075*cfb92d14SAndroid Build Coastguard Worker
1076*cfb92d14SAndroid Build Coastguard Worker {
1077*cfb92d14SAndroid Build Coastguard Worker // After two labels we have a pointer label jumping back to
1078*cfb92d14SAndroid Build Coastguard Worker // start of the first label. Name itself starts at offset 3
1079*cfb92d14SAndroid Build Coastguard Worker // (first 3 bytes are unused).
1080*cfb92d14SAndroid Build Coastguard Worker
1081*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {0, 0, 0, 3, 'F', 'O', 'O', 2, 'B', 'A', 0xc0, 3};
1082*cfb92d14SAndroid Build Coastguard Worker
1083*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1084*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kEncodedName));
1085*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("looped-two-labels", kEncodedName, sizeof(kEncodedName));
1086*cfb92d14SAndroid Build Coastguard Worker offset = 3;
1087*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ParseName(*message, offset) == kErrorParse);
1088*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::ReadName(*message, offset, name) == kErrorParse);
1089*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::Name::CompareName(*message, offset, "FOO.BA.") == kErrorParse);
1090*cfb92d14SAndroid Build Coastguard Worker }
1091*cfb92d14SAndroid Build Coastguard Worker
1092*cfb92d14SAndroid Build Coastguard Worker {
1093*cfb92d14SAndroid Build Coastguard Worker // Same as last case, but pointer label now points to
1094*cfb92d14SAndroid Build Coastguard Worker // immediately before the first label (at offset 2). The name
1095*cfb92d14SAndroid Build Coastguard Worker // is now valid.
1096*cfb92d14SAndroid Build Coastguard Worker
1097*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEncodedName[] = {0, 0, 0, 3, 'F', 'O', 'O', 2, 'B', 'A', 0xc0, 2};
1098*cfb92d14SAndroid Build Coastguard Worker
1099*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1100*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kEncodedName));
1101*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("valid-name", kEncodedName, sizeof(kEncodedName));
1102*cfb92d14SAndroid Build Coastguard Worker offset = 3;
1103*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
1104*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == sizeof(kEncodedName));
1105*cfb92d14SAndroid Build Coastguard Worker
1106*cfb92d14SAndroid Build Coastguard Worker offset = 3;
1107*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ReadName(*message, offset, name));
1108*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == sizeof(kEncodedName));
1109*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, "FOO.BA.") == 0);
1110*cfb92d14SAndroid Build Coastguard Worker printf("Read name =\"%s\"\n", name);
1111*cfb92d14SAndroid Build Coastguard Worker }
1112*cfb92d14SAndroid Build Coastguard Worker
1113*cfb92d14SAndroid Build Coastguard Worker message->Free();
1114*cfb92d14SAndroid Build Coastguard Worker message2->Free();
1115*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
1116*cfb92d14SAndroid Build Coastguard Worker }
1117*cfb92d14SAndroid Build Coastguard Worker
TestHeaderAndResourceRecords(void)1118*cfb92d14SAndroid Build Coastguard Worker void TestHeaderAndResourceRecords(void)
1119*cfb92d14SAndroid Build Coastguard Worker {
1120*cfb92d14SAndroid Build Coastguard Worker enum
1121*cfb92d14SAndroid Build Coastguard Worker {
1122*cfb92d14SAndroid Build Coastguard Worker kHeaderOffset = 0,
1123*cfb92d14SAndroid Build Coastguard Worker kQuestionCount = 1,
1124*cfb92d14SAndroid Build Coastguard Worker kAnswerCount = 2,
1125*cfb92d14SAndroid Build Coastguard Worker kAdditionalCount = 5,
1126*cfb92d14SAndroid Build Coastguard Worker kTtl = 7200,
1127*cfb92d14SAndroid Build Coastguard Worker kTxtTtl = 7300,
1128*cfb92d14SAndroid Build Coastguard Worker kSrvPort = 1234,
1129*cfb92d14SAndroid Build Coastguard Worker kSrvPriority = 1,
1130*cfb92d14SAndroid Build Coastguard Worker kSrvWeight = 2,
1131*cfb92d14SAndroid Build Coastguard Worker kMaxSize = 600,
1132*cfb92d14SAndroid Build Coastguard Worker };
1133*cfb92d14SAndroid Build Coastguard Worker
1134*cfb92d14SAndroid Build Coastguard Worker const char kMessageString[] = "DnsMessage";
1135*cfb92d14SAndroid Build Coastguard Worker const char kDomainName[] = "example.com.";
1136*cfb92d14SAndroid Build Coastguard Worker const char kServiceLabels[] = "_service._udp";
1137*cfb92d14SAndroid Build Coastguard Worker const char kServiceName[] = "_service._udp.example.com.";
1138*cfb92d14SAndroid Build Coastguard Worker const char kInstance1Label[] = "inst1";
1139*cfb92d14SAndroid Build Coastguard Worker const char kInstance2Label[] = "instance.2"; // Instance label includes dot '.' character.
1140*cfb92d14SAndroid Build Coastguard Worker const char kInstance1Name[] = "inst1._service._udp.example.com.";
1141*cfb92d14SAndroid Build Coastguard Worker const char kInstance2Name[] = "instance.2._service._udp.example.com.";
1142*cfb92d14SAndroid Build Coastguard Worker const char kHostName[] = "host.example.com.";
1143*cfb92d14SAndroid Build Coastguard Worker const uint8_t kTxtData[] = {9, 'k', 'e', 'y', '=', 'v', 'a', 'l', 'u', 'e', 0};
1144*cfb92d14SAndroid Build Coastguard Worker const char kHostAddress[] = "fd00::abcd:";
1145*cfb92d14SAndroid Build Coastguard Worker
1146*cfb92d14SAndroid Build Coastguard Worker const char *kInstanceLabels[] = {kInstance1Label, kInstance2Label};
1147*cfb92d14SAndroid Build Coastguard Worker const char *kInstanceNames[] = {kInstance1Name, kInstance2Name};
1148*cfb92d14SAndroid Build Coastguard Worker
1149*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
1150*cfb92d14SAndroid Build Coastguard Worker MessagePool *messagePool;
1151*cfb92d14SAndroid Build Coastguard Worker Message *message;
1152*cfb92d14SAndroid Build Coastguard Worker Dns::Header header;
1153*cfb92d14SAndroid Build Coastguard Worker uint16_t messageId;
1154*cfb92d14SAndroid Build Coastguard Worker uint16_t headerOffset;
1155*cfb92d14SAndroid Build Coastguard Worker uint16_t offset;
1156*cfb92d14SAndroid Build Coastguard Worker uint16_t numRecords;
1157*cfb92d14SAndroid Build Coastguard Worker uint16_t len;
1158*cfb92d14SAndroid Build Coastguard Worker uint16_t serviceNameOffset;
1159*cfb92d14SAndroid Build Coastguard Worker uint16_t hostNameOffset;
1160*cfb92d14SAndroid Build Coastguard Worker uint16_t answerSectionOffset;
1161*cfb92d14SAndroid Build Coastguard Worker uint16_t additionalSectionOffset;
1162*cfb92d14SAndroid Build Coastguard Worker uint16_t index;
1163*cfb92d14SAndroid Build Coastguard Worker Dns::PtrRecord ptrRecord;
1164*cfb92d14SAndroid Build Coastguard Worker Dns::SrvRecord srvRecord;
1165*cfb92d14SAndroid Build Coastguard Worker Dns::TxtRecord txtRecord;
1166*cfb92d14SAndroid Build Coastguard Worker Dns::AaaaRecord aaaaRecord;
1167*cfb92d14SAndroid Build Coastguard Worker Dns::ResourceRecord record;
1168*cfb92d14SAndroid Build Coastguard Worker Ip6::Address hostAddress;
1169*cfb92d14SAndroid Build Coastguard Worker
1170*cfb92d14SAndroid Build Coastguard Worker Dns::Name::LabelBuffer label;
1171*cfb92d14SAndroid Build Coastguard Worker Dns::Name::Buffer name;
1172*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
1173*cfb92d14SAndroid Build Coastguard Worker
1174*cfb92d14SAndroid Build Coastguard Worker printf("================================================================\n");
1175*cfb92d14SAndroid Build Coastguard Worker printf("TestHeaderAndResourceRecords()\n");
1176*cfb92d14SAndroid Build Coastguard Worker
1177*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
1178*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
1179*cfb92d14SAndroid Build Coastguard Worker
1180*cfb92d14SAndroid Build Coastguard Worker messagePool = &instance->Get<MessagePool>();
1181*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
1182*cfb92d14SAndroid Build Coastguard Worker
1183*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
1184*cfb92d14SAndroid Build Coastguard Worker printf("Preparing the message\n");
1185*cfb92d14SAndroid Build Coastguard Worker
1186*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kMessageString));
1187*cfb92d14SAndroid Build Coastguard Worker
1188*cfb92d14SAndroid Build Coastguard Worker // Header
1189*cfb92d14SAndroid Build Coastguard Worker
1190*cfb92d14SAndroid Build Coastguard Worker headerOffset = message->GetLength();
1191*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(header.SetRandomMessageId());
1192*cfb92d14SAndroid Build Coastguard Worker messageId = header.GetMessageId();
1193*cfb92d14SAndroid Build Coastguard Worker header.SetType(Dns::Header::kTypeResponse);
1194*cfb92d14SAndroid Build Coastguard Worker header.SetQuestionCount(kQuestionCount);
1195*cfb92d14SAndroid Build Coastguard Worker header.SetAnswerCount(kAnswerCount);
1196*cfb92d14SAndroid Build Coastguard Worker header.SetAdditionalRecordCount(kAdditionalCount);
1197*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(header));
1198*cfb92d14SAndroid Build Coastguard Worker message->SetOffset(headerOffset);
1199*cfb92d14SAndroid Build Coastguard Worker
1200*cfb92d14SAndroid Build Coastguard Worker // Question section
1201*cfb92d14SAndroid Build Coastguard Worker
1202*cfb92d14SAndroid Build Coastguard Worker serviceNameOffset = message->GetLength() - headerOffset;
1203*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendMultipleLabels(kServiceLabels, *message));
1204*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(kDomainName, *message));
1205*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(Dns::Question(Dns::ResourceRecord::kTypePtr)));
1206*cfb92d14SAndroid Build Coastguard Worker
1207*cfb92d14SAndroid Build Coastguard Worker // Answer section
1208*cfb92d14SAndroid Build Coastguard Worker
1209*cfb92d14SAndroid Build Coastguard Worker answerSectionOffset = message->GetLength();
1210*cfb92d14SAndroid Build Coastguard Worker
1211*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceLabel : kInstanceLabels)
1212*cfb92d14SAndroid Build Coastguard Worker {
1213*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(serviceNameOffset, *message));
1214*cfb92d14SAndroid Build Coastguard Worker ptrRecord.Init();
1215*cfb92d14SAndroid Build Coastguard Worker ptrRecord.SetTtl(kTtl);
1216*cfb92d14SAndroid Build Coastguard Worker offset = message->GetLength();
1217*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(ptrRecord));
1218*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendLabel(instanceLabel, *message));
1219*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(serviceNameOffset, *message));
1220*cfb92d14SAndroid Build Coastguard Worker ptrRecord.SetLength(message->GetLength() - offset - sizeof(Dns::ResourceRecord));
1221*cfb92d14SAndroid Build Coastguard Worker message->Write(offset, ptrRecord);
1222*cfb92d14SAndroid Build Coastguard Worker }
1223*cfb92d14SAndroid Build Coastguard Worker
1224*cfb92d14SAndroid Build Coastguard Worker // Additional section
1225*cfb92d14SAndroid Build Coastguard Worker
1226*cfb92d14SAndroid Build Coastguard Worker additionalSectionOffset = message->GetLength();
1227*cfb92d14SAndroid Build Coastguard Worker
1228*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceName : kInstanceNames)
1229*cfb92d14SAndroid Build Coastguard Worker {
1230*cfb92d14SAndroid Build Coastguard Worker uint16_t instanceNameOffset = message->GetLength() - headerOffset;
1231*cfb92d14SAndroid Build Coastguard Worker
1232*cfb92d14SAndroid Build Coastguard Worker // SRV record
1233*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(instanceName, *message));
1234*cfb92d14SAndroid Build Coastguard Worker srvRecord.Init();
1235*cfb92d14SAndroid Build Coastguard Worker srvRecord.SetTtl(kTtl);
1236*cfb92d14SAndroid Build Coastguard Worker srvRecord.SetPort(kSrvPort);
1237*cfb92d14SAndroid Build Coastguard Worker srvRecord.SetWeight(kSrvWeight);
1238*cfb92d14SAndroid Build Coastguard Worker srvRecord.SetPriority(kSrvPriority);
1239*cfb92d14SAndroid Build Coastguard Worker offset = message->GetLength();
1240*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(srvRecord));
1241*cfb92d14SAndroid Build Coastguard Worker hostNameOffset = message->GetLength() - headerOffset;
1242*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendName(kHostName, *message));
1243*cfb92d14SAndroid Build Coastguard Worker srvRecord.SetLength(message->GetLength() - offset - sizeof(Dns::ResourceRecord));
1244*cfb92d14SAndroid Build Coastguard Worker message->Write(offset, srvRecord);
1245*cfb92d14SAndroid Build Coastguard Worker
1246*cfb92d14SAndroid Build Coastguard Worker // TXT record
1247*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(instanceNameOffset, *message));
1248*cfb92d14SAndroid Build Coastguard Worker txtRecord.Init();
1249*cfb92d14SAndroid Build Coastguard Worker txtRecord.SetTtl(kTxtTtl);
1250*cfb92d14SAndroid Build Coastguard Worker txtRecord.SetLength(sizeof(kTxtData));
1251*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(txtRecord));
1252*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kTxtData));
1253*cfb92d14SAndroid Build Coastguard Worker }
1254*cfb92d14SAndroid Build Coastguard Worker
1255*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(hostAddress.FromString(kHostAddress));
1256*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::AppendPointerLabel(hostNameOffset, *message));
1257*cfb92d14SAndroid Build Coastguard Worker aaaaRecord.Init();
1258*cfb92d14SAndroid Build Coastguard Worker aaaaRecord.SetTtl(kTtl);
1259*cfb92d14SAndroid Build Coastguard Worker aaaaRecord.SetAddress(hostAddress);
1260*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(aaaaRecord));
1261*cfb92d14SAndroid Build Coastguard Worker
1262*cfb92d14SAndroid Build Coastguard Worker // Dump the entire message
1263*cfb92d14SAndroid Build Coastguard Worker
1264*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() < kMaxSize, "Message is too long");
1265*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, buffer, message->GetLength()));
1266*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("message", buffer, message->GetLength());
1267*cfb92d14SAndroid Build Coastguard Worker
1268*cfb92d14SAndroid Build Coastguard Worker printf("----------------------------------------------------------------\n");
1269*cfb92d14SAndroid Build Coastguard Worker printf("Parse and verify the message\n");
1270*cfb92d14SAndroid Build Coastguard Worker
1271*cfb92d14SAndroid Build Coastguard Worker offset = 0;
1272*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(offset, kMessageString), "Message header does not match");
1273*cfb92d14SAndroid Build Coastguard Worker offset += sizeof(kMessageString);
1274*cfb92d14SAndroid Build Coastguard Worker
1275*cfb92d14SAndroid Build Coastguard Worker // Header
1276*cfb92d14SAndroid Build Coastguard Worker
1277*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == headerOffset, "headerOffset is incorrect");
1278*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(offset, header));
1279*cfb92d14SAndroid Build Coastguard Worker offset += sizeof(header);
1280*cfb92d14SAndroid Build Coastguard Worker
1281*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(header.GetMessageId() == messageId);
1282*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(header.GetType() == Dns::Header::kTypeResponse);
1283*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(header.GetQuestionCount() == kQuestionCount);
1284*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(header.GetAnswerCount() == kAnswerCount);
1285*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(header.GetAdditionalRecordCount() == kAdditionalCount);
1286*cfb92d14SAndroid Build Coastguard Worker
1287*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
1288*cfb92d14SAndroid Build Coastguard Worker printf("Question Section\n");
1289*cfb92d14SAndroid Build Coastguard Worker
1290*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kServiceName), "Question name does not match");
1291*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(offset, Dns::Question(Dns::ResourceRecord::kTypePtr)));
1292*cfb92d14SAndroid Build Coastguard Worker offset += sizeof(Dns::Question);
1293*cfb92d14SAndroid Build Coastguard Worker
1294*cfb92d14SAndroid Build Coastguard Worker printf("PTR for \"%s\"\n", kServiceName);
1295*cfb92d14SAndroid Build Coastguard Worker
1296*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
1297*cfb92d14SAndroid Build Coastguard Worker printf("Answer Section\n");
1298*cfb92d14SAndroid Build Coastguard Worker
1299*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == answerSectionOffset, "answer section offset is incorrect");
1300*cfb92d14SAndroid Build Coastguard Worker
1301*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceLabel : kInstanceLabels)
1302*cfb92d14SAndroid Build Coastguard Worker {
1303*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kServiceName));
1304*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, ptrRecord));
1305*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ptrRecord.GetTtl() == kTtl, "Read PTR is incorrect");
1306*cfb92d14SAndroid Build Coastguard Worker
1307*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(ptrRecord.ReadPtrName(*message, offset, label, name));
1308*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(label, instanceLabel) == 0, "Inst label is incorrect");
1309*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kServiceName) == 0);
1310*cfb92d14SAndroid Build Coastguard Worker
1311*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" PTR %u %d \"%s.%s\"\n", kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength(), label,
1312*cfb92d14SAndroid Build Coastguard Worker name);
1313*cfb92d14SAndroid Build Coastguard Worker }
1314*cfb92d14SAndroid Build Coastguard Worker
1315*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
1316*cfb92d14SAndroid Build Coastguard Worker
1317*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1318*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ParseRecords(*message, offset, kAnswerCount));
1319*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
1320*cfb92d14SAndroid Build Coastguard Worker
1321*cfb92d14SAndroid Build Coastguard Worker printf("Use FindRecord() to find and iterate through all the records:\n");
1322*cfb92d14SAndroid Build Coastguard Worker
1323*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1324*cfb92d14SAndroid Build Coastguard Worker numRecords = kAnswerCount;
1325*cfb92d14SAndroid Build Coastguard Worker
1326*cfb92d14SAndroid Build Coastguard Worker while (numRecords > 0)
1327*cfb92d14SAndroid Build Coastguard Worker {
1328*cfb92d14SAndroid Build Coastguard Worker uint16_t prevNumRecords = numRecords;
1329*cfb92d14SAndroid Build Coastguard Worker
1330*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(kServiceName)));
1331*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(numRecords == prevNumRecords - 1, "Incorrect num records");
1332*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, ptrRecord));
1333*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ptrRecord.GetTtl() == kTtl, "Read PTR is incorrect");
1334*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(ptrRecord.ReadPtrName(*message, offset, label, name));
1335*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" PTR %u %d inst:\"%s\" at \"%s\"\n", kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength(),
1336*cfb92d14SAndroid Build Coastguard Worker label, name);
1337*cfb92d14SAndroid Build Coastguard Worker }
1338*cfb92d14SAndroid Build Coastguard Worker
1339*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
1340*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(kServiceName)) ==
1341*cfb92d14SAndroid Build Coastguard Worker kErrorNotFound,
1342*cfb92d14SAndroid Build Coastguard Worker "FindRecord did not fail with no records");
1343*cfb92d14SAndroid Build Coastguard Worker
1344*cfb92d14SAndroid Build Coastguard Worker // Use `ReadRecord()` with a non-matching record type. Verify that it correct skips over the record.
1345*cfb92d14SAndroid Build Coastguard Worker
1346*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1347*cfb92d14SAndroid Build Coastguard Worker numRecords = kAnswerCount;
1348*cfb92d14SAndroid Build Coastguard Worker
1349*cfb92d14SAndroid Build Coastguard Worker while (numRecords > 0)
1350*cfb92d14SAndroid Build Coastguard Worker {
1351*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(kServiceName)));
1352*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, srvRecord) == kErrorNotFound,
1353*cfb92d14SAndroid Build Coastguard Worker "ReadRecord() did not fail with non-matching type");
1354*cfb92d14SAndroid Build Coastguard Worker }
1355*cfb92d14SAndroid Build Coastguard Worker
1356*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
1357*cfb92d14SAndroid Build Coastguard Worker
1358*cfb92d14SAndroid Build Coastguard Worker // Use `FindRecord` with a non-matching name. Verify that it correctly skips over all records.
1359*cfb92d14SAndroid Build Coastguard Worker
1360*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1361*cfb92d14SAndroid Build Coastguard Worker numRecords = kAnswerCount;
1362*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(kInstance1Name)) ==
1363*cfb92d14SAndroid Build Coastguard Worker kErrorNotFound,
1364*cfb92d14SAndroid Build Coastguard Worker "FindRecord did not fail with non-matching name");
1365*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(numRecords == 0, "Incorrect num records");
1366*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
1367*cfb92d14SAndroid Build Coastguard Worker
1368*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
1369*cfb92d14SAndroid Build Coastguard Worker printf("Additional Section\n");
1370*cfb92d14SAndroid Build Coastguard Worker
1371*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceName : kInstanceNames)
1372*cfb92d14SAndroid Build Coastguard Worker {
1373*cfb92d14SAndroid Build Coastguard Worker uint16_t savedOffset;
1374*cfb92d14SAndroid Build Coastguard Worker
1375*cfb92d14SAndroid Build Coastguard Worker // SRV record
1376*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, instanceName));
1377*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, srvRecord));
1378*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(srvRecord.GetTtl() == kTtl);
1379*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(srvRecord.GetPort() == kSrvPort);
1380*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(srvRecord.GetWeight() == kSrvWeight);
1381*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(srvRecord.GetPriority() == kSrvPriority);
1382*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(srvRecord.ReadTargetHostName(*message, offset, name));
1383*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(name, kHostName) == 0);
1384*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" SRV %u %d %d %d %d \"%s\"\n", instanceName, srvRecord.GetTtl(), srvRecord.GetLength(),
1385*cfb92d14SAndroid Build Coastguard Worker srvRecord.GetPort(), srvRecord.GetWeight(), srvRecord.GetPriority(), name);
1386*cfb92d14SAndroid Build Coastguard Worker
1387*cfb92d14SAndroid Build Coastguard Worker // TXT record
1388*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, instanceName));
1389*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, txtRecord));
1390*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtRecord.GetTtl() == kTxtTtl);
1391*cfb92d14SAndroid Build Coastguard Worker savedOffset = offset;
1392*cfb92d14SAndroid Build Coastguard Worker len = sizeof(buffer);
1393*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(txtRecord.ReadTxtData(*message, offset, buffer, len));
1394*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(len == sizeof(kTxtData));
1395*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kTxtData, len) == 0);
1396*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" TXT %u %d \"%s\"\n", instanceName, txtRecord.GetTtl(), txtRecord.GetLength(),
1397*cfb92d14SAndroid Build Coastguard Worker reinterpret_cast<const char *>(buffer));
1398*cfb92d14SAndroid Build Coastguard Worker
1399*cfb92d14SAndroid Build Coastguard Worker // Partial read of TXT data
1400*cfb92d14SAndroid Build Coastguard Worker len = sizeof(kTxtData) - 1;
1401*cfb92d14SAndroid Build Coastguard Worker memset(buffer, 0, sizeof(buffer));
1402*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtRecord.ReadTxtData(*message, savedOffset, buffer, len) == kErrorNoBufs);
1403*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(len == sizeof(kTxtData) - 1);
1404*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kTxtData, len) == 0);
1405*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(savedOffset == offset);
1406*cfb92d14SAndroid Build Coastguard Worker }
1407*cfb92d14SAndroid Build Coastguard Worker
1408*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::CompareName(*message, offset, kHostName));
1409*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, aaaaRecord));
1410*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aaaaRecord.GetTtl() == kTtl);
1411*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aaaaRecord.GetAddress() == hostAddress);
1412*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" AAAA %u %d \"%s\"\n", kHostName, aaaaRecord.GetTtl(), aaaaRecord.GetLength(),
1413*cfb92d14SAndroid Build Coastguard Worker aaaaRecord.GetAddress().ToString().AsCString());
1414*cfb92d14SAndroid Build Coastguard Worker
1415*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == message->GetLength(), "offset is incorrect after additional section parse");
1416*cfb92d14SAndroid Build Coastguard Worker
1417*cfb92d14SAndroid Build Coastguard Worker // Use `ParseRecords()` to parse all records
1418*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1419*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ParseRecords(*message, offset, kAdditionalCount));
1420*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == message->GetLength(), "offset is incorrect after additional section parse");
1421*cfb92d14SAndroid Build Coastguard Worker
1422*cfb92d14SAndroid Build Coastguard Worker printf("Use FindRecord() to search for specific name:\n");
1423*cfb92d14SAndroid Build Coastguard Worker
1424*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceName : kInstanceNames)
1425*cfb92d14SAndroid Build Coastguard Worker {
1426*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1427*cfb92d14SAndroid Build Coastguard Worker numRecords = kAdditionalCount;
1428*cfb92d14SAndroid Build Coastguard Worker
1429*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(instanceName)));
1430*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, srvRecord));
1431*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::Name::ParseName(*message, offset));
1432*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" SRV %u %d %d %d %d\n", instanceName, srvRecord.GetTtl(), srvRecord.GetLength(),
1433*cfb92d14SAndroid Build Coastguard Worker srvRecord.GetPort(), srvRecord.GetWeight(), srvRecord.GetPriority());
1434*cfb92d14SAndroid Build Coastguard Worker
1435*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(instanceName)));
1436*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, txtRecord));
1437*cfb92d14SAndroid Build Coastguard Worker offset += txtRecord.GetLength();
1438*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" TXT %u %d\n", instanceName, txtRecord.GetTtl(), txtRecord.GetLength());
1439*cfb92d14SAndroid Build Coastguard Worker
1440*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(instanceName)) ==
1441*cfb92d14SAndroid Build Coastguard Worker kErrorNotFound,
1442*cfb92d14SAndroid Build Coastguard Worker "FindRecord() did not fail with no more records");
1443*cfb92d14SAndroid Build Coastguard Worker
1444*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == message->GetLength(), "offset is incorrect after additional section parse");
1445*cfb92d14SAndroid Build Coastguard Worker }
1446*cfb92d14SAndroid Build Coastguard Worker
1447*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1448*cfb92d14SAndroid Build Coastguard Worker numRecords = kAdditionalCount;
1449*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, numRecords, Dns::Name(kHostName)));
1450*cfb92d14SAndroid Build Coastguard Worker
1451*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, record));
1452*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(record.GetType() == Dns::ResourceRecord::kTypeAaaa);
1453*cfb92d14SAndroid Build Coastguard Worker offset += record.GetLength();
1454*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == message->GetLength(), "offset is incorrect after additional section parse");
1455*cfb92d14SAndroid Build Coastguard Worker
1456*cfb92d14SAndroid Build Coastguard Worker printf("Use FindRecord() to search for specific records:\n");
1457*cfb92d14SAndroid Build Coastguard Worker printf(" Answer Section\n");
1458*cfb92d14SAndroid Build Coastguard Worker
1459*cfb92d14SAndroid Build Coastguard Worker for (index = 0; index < GetArrayLength(kInstanceNames); index++)
1460*cfb92d14SAndroid Build Coastguard Worker {
1461*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1462*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(
1463*cfb92d14SAndroid Build Coastguard Worker Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName), ptrRecord));
1464*cfb92d14SAndroid Build Coastguard Worker
1465*cfb92d14SAndroid Build Coastguard Worker printf(" index:%d -> \"%s\" PTR %u %d\n", index, kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength());
1466*cfb92d14SAndroid Build Coastguard Worker }
1467*cfb92d14SAndroid Build Coastguard Worker
1468*cfb92d14SAndroid Build Coastguard Worker // Check `FindRecord()` failure with non-matching name, record type, or bad index.
1469*cfb92d14SAndroid Build Coastguard Worker
1470*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1471*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName),
1472*cfb92d14SAndroid Build Coastguard Worker ptrRecord) == kErrorNotFound,
1473*cfb92d14SAndroid Build Coastguard Worker "FindRecord() did not fail with bad index");
1474*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
1475*cfb92d14SAndroid Build Coastguard Worker
1476*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1477*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kInstance1Name),
1478*cfb92d14SAndroid Build Coastguard Worker ptrRecord) == kErrorNotFound,
1479*cfb92d14SAndroid Build Coastguard Worker "FindRecord() did not fail with bad index");
1480*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
1481*cfb92d14SAndroid Build Coastguard Worker
1482*cfb92d14SAndroid Build Coastguard Worker offset = answerSectionOffset;
1483*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName),
1484*cfb92d14SAndroid Build Coastguard Worker txtRecord) == kErrorNotFound,
1485*cfb92d14SAndroid Build Coastguard Worker "FindRecord() did not fail with bad index");
1486*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
1487*cfb92d14SAndroid Build Coastguard Worker
1488*cfb92d14SAndroid Build Coastguard Worker printf(" Additional Section\n");
1489*cfb92d14SAndroid Build Coastguard Worker
1490*cfb92d14SAndroid Build Coastguard Worker for (const char *instanceName : kInstanceNames)
1491*cfb92d14SAndroid Build Coastguard Worker {
1492*cfb92d14SAndroid Build Coastguard Worker // There is a single SRV and TXT entry for each instance
1493*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1494*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 0,
1495*cfb92d14SAndroid Build Coastguard Worker Dns::Name(instanceName), srvRecord));
1496*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" SRV %u %d %d %d %d \n", instanceName, srvRecord.GetTtl(), srvRecord.GetLength(),
1497*cfb92d14SAndroid Build Coastguard Worker srvRecord.GetPort(), srvRecord.GetWeight(), srvRecord.GetPriority());
1498*cfb92d14SAndroid Build Coastguard Worker
1499*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1500*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 0,
1501*cfb92d14SAndroid Build Coastguard Worker Dns::Name(instanceName), txtRecord));
1502*cfb92d14SAndroid Build Coastguard Worker printf(" \"%s\" TXT %u %d\n", instanceName, txtRecord.GetTtl(), txtRecord.GetLength());
1503*cfb92d14SAndroid Build Coastguard Worker
1504*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1505*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 1,
1506*cfb92d14SAndroid Build Coastguard Worker Dns::Name(instanceName), srvRecord) == kErrorNotFound);
1507*cfb92d14SAndroid Build Coastguard Worker
1508*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1509*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 1,
1510*cfb92d14SAndroid Build Coastguard Worker Dns::Name(instanceName), txtRecord) == kErrorNotFound);
1511*cfb92d14SAndroid Build Coastguard Worker }
1512*cfb92d14SAndroid Build Coastguard Worker
1513*cfb92d14SAndroid Build Coastguard Worker for (index = 0; index < kAdditionalCount; index++)
1514*cfb92d14SAndroid Build Coastguard Worker {
1515*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1516*cfb92d14SAndroid Build Coastguard Worker // Find record with empty name (matching any) and any type.
1517*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, index, Dns::Name(), record));
1518*cfb92d14SAndroid Build Coastguard Worker }
1519*cfb92d14SAndroid Build Coastguard Worker
1520*cfb92d14SAndroid Build Coastguard Worker offset = additionalSectionOffset;
1521*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, index, Dns::Name(), record) ==
1522*cfb92d14SAndroid Build Coastguard Worker kErrorNotFound);
1523*cfb92d14SAndroid Build Coastguard Worker
1524*cfb92d14SAndroid Build Coastguard Worker message->Free();
1525*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
1526*cfb92d14SAndroid Build Coastguard Worker }
1527*cfb92d14SAndroid Build Coastguard Worker
TestDnsTxtEntry(void)1528*cfb92d14SAndroid Build Coastguard Worker void TestDnsTxtEntry(void)
1529*cfb92d14SAndroid Build Coastguard Worker {
1530*cfb92d14SAndroid Build Coastguard Worker enum
1531*cfb92d14SAndroid Build Coastguard Worker {
1532*cfb92d14SAndroid Build Coastguard Worker kMaxTxtDataSize = 255,
1533*cfb92d14SAndroid Build Coastguard Worker };
1534*cfb92d14SAndroid Build Coastguard Worker
1535*cfb92d14SAndroid Build Coastguard Worker struct EncodedTxtData
1536*cfb92d14SAndroid Build Coastguard Worker {
1537*cfb92d14SAndroid Build Coastguard Worker const uint8_t *mData;
1538*cfb92d14SAndroid Build Coastguard Worker uint8_t mLength;
1539*cfb92d14SAndroid Build Coastguard Worker };
1540*cfb92d14SAndroid Build Coastguard Worker
1541*cfb92d14SAndroid Build Coastguard Worker const char kKey1[] = "key";
1542*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue1[] = {'v', 'a', 'l', 'u', 'e'};
1543*cfb92d14SAndroid Build Coastguard Worker
1544*cfb92d14SAndroid Build Coastguard Worker const char kKey2[] = "E";
1545*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue2[] = {'m', 'c', '^', '2'};
1546*cfb92d14SAndroid Build Coastguard Worker
1547*cfb92d14SAndroid Build Coastguard Worker const char kKey3[] = "space key";
1548*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue3[] = {'=', 0, '='};
1549*cfb92d14SAndroid Build Coastguard Worker
1550*cfb92d14SAndroid Build Coastguard Worker const char kKey4[] = "123456789"; // Max recommended length key
1551*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue4[] = {0};
1552*cfb92d14SAndroid Build Coastguard Worker
1553*cfb92d14SAndroid Build Coastguard Worker const char kKey5[] = "1234567890"; // Longer than recommended key
1554*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue5[] = {'a'};
1555*cfb92d14SAndroid Build Coastguard Worker
1556*cfb92d14SAndroid Build Coastguard Worker const char kKey6[] = "boolKey"; // Should be encoded as "boolKey" (without `=`).
1557*cfb92d14SAndroid Build Coastguard Worker const char kKey7[] = "emptyKey"; // Should be encoded as "emptyKey=".
1558*cfb92d14SAndroid Build Coastguard Worker
1559*cfb92d14SAndroid Build Coastguard Worker const char kKey8[] = "1234567890123456789012345678901234567890123456789012345678901234567890";
1560*cfb92d14SAndroid Build Coastguard Worker const uint8_t kValue8[] = "abcd";
1561*cfb92d14SAndroid Build Coastguard Worker
1562*cfb92d14SAndroid Build Coastguard Worker // Invalid key
1563*cfb92d14SAndroid Build Coastguard Worker const char kShortKey[] = "";
1564*cfb92d14SAndroid Build Coastguard Worker
1565*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt1[] = {9, 'k', 'e', 'y', '=', 'v', 'a', 'l', 'u', 'e'};
1566*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt2[] = {6, 'E', '=', 'm', 'c', '^', '2'};
1567*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt3[] = {13, 's', 'p', 'a', 'c', 'e', ' ', 'k', 'e', 'y', '=', '=', 0, '='};
1568*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt4[] = {11, '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', 0};
1569*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt5[] = {12, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '=', 'a'};
1570*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt6[] = {7, 'b', 'o', 'o', 'l', 'K', 'e', 'y'};
1571*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt7[] = {9, 'e', 'm', 'p', 't', 'y', 'K', 'e', 'y', '='};
1572*cfb92d14SAndroid Build Coastguard Worker const uint8_t kEncodedTxt8[] = {
1573*cfb92d14SAndroid Build Coastguard Worker 75, // length
1574*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 10
1575*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 20
1576*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 30
1577*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 40
1578*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 50
1579*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 60
1580*cfb92d14SAndroid Build Coastguard Worker '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 70
1581*cfb92d14SAndroid Build Coastguard Worker '=', 'a', 'b', 'c', 'd',
1582*cfb92d14SAndroid Build Coastguard Worker };
1583*cfb92d14SAndroid Build Coastguard Worker
1584*cfb92d14SAndroid Build Coastguard Worker const uint8_t kInvalidEncodedTxt1[] = {4, 'a', '=', 'b'}; // Incorrect length
1585*cfb92d14SAndroid Build Coastguard Worker
1586*cfb92d14SAndroid Build Coastguard Worker // Special encoded txt data with zero strings and string starting
1587*cfb92d14SAndroid Build Coastguard Worker // with '=' (missing key) which should be skipped over silently.
1588*cfb92d14SAndroid Build Coastguard Worker const uint8_t kSpecialEncodedTxt[] = {0, 0, 3, 'A', '=', 'B', 2, '=', 'C', 3, 'D', '=', 'E', 3, '=', '1', '2'};
1589*cfb92d14SAndroid Build Coastguard Worker
1590*cfb92d14SAndroid Build Coastguard Worker const Dns::TxtEntry kTxtEntries[] = {
1591*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey1, kValue1, sizeof(kValue1)),
1592*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey2, kValue2, sizeof(kValue2)),
1593*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey3, kValue3, sizeof(kValue3)),
1594*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey4, kValue4, sizeof(kValue4)),
1595*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey5, kValue5, sizeof(kValue5)),
1596*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey6, nullptr, 0),
1597*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey7, kValue1, 0),
1598*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry(kKey8, kValue8, sizeof(kValue8)),
1599*cfb92d14SAndroid Build Coastguard Worker };
1600*cfb92d14SAndroid Build Coastguard Worker
1601*cfb92d14SAndroid Build Coastguard Worker const EncodedTxtData kEncodedTxtData[] = {
1602*cfb92d14SAndroid Build Coastguard Worker {kEncodedTxt1, sizeof(kEncodedTxt1)}, {kEncodedTxt2, sizeof(kEncodedTxt2)},
1603*cfb92d14SAndroid Build Coastguard Worker {kEncodedTxt3, sizeof(kEncodedTxt3)}, {kEncodedTxt4, sizeof(kEncodedTxt4)},
1604*cfb92d14SAndroid Build Coastguard Worker {kEncodedTxt5, sizeof(kEncodedTxt5)}, {kEncodedTxt6, sizeof(kEncodedTxt6)},
1605*cfb92d14SAndroid Build Coastguard Worker {kEncodedTxt7, sizeof(kEncodedTxt7)}};
1606*cfb92d14SAndroid Build Coastguard Worker
1607*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
1608*cfb92d14SAndroid Build Coastguard Worker MessagePool *messagePool;
1609*cfb92d14SAndroid Build Coastguard Worker Message *message;
1610*cfb92d14SAndroid Build Coastguard Worker uint8_t txtData[kMaxTxtDataSize];
1611*cfb92d14SAndroid Build Coastguard Worker uint16_t txtDataLength;
1612*cfb92d14SAndroid Build Coastguard Worker uint8_t index;
1613*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry txtEntry;
1614*cfb92d14SAndroid Build Coastguard Worker Dns::TxtEntry::Iterator iterator;
1615*cfb92d14SAndroid Build Coastguard Worker MutableData<kWithUint16Length> data;
1616*cfb92d14SAndroid Build Coastguard Worker
1617*cfb92d14SAndroid Build Coastguard Worker printf("================================================================\n");
1618*cfb92d14SAndroid Build Coastguard Worker printf("TestDnsTxtEntry()\n");
1619*cfb92d14SAndroid Build Coastguard Worker
1620*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
1621*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
1622*cfb92d14SAndroid Build Coastguard Worker
1623*cfb92d14SAndroid Build Coastguard Worker messagePool = &instance->Get<MessagePool>();
1624*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
1625*cfb92d14SAndroid Build Coastguard Worker
1626*cfb92d14SAndroid Build Coastguard Worker data.Init(txtData, sizeof(txtData));
1627*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::TxtEntry::AppendEntries(kTxtEntries, GetArrayLength(kTxtEntries), data));
1628*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(data.GetBytes() == txtData);
1629*cfb92d14SAndroid Build Coastguard Worker txtDataLength = data.GetLength();
1630*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtDataLength < kMaxTxtDataSize, "TXT data is too long");
1631*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("txt data", txtData, txtDataLength);
1632*cfb92d14SAndroid Build Coastguard Worker
1633*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::TxtEntry::AppendEntries(kTxtEntries, GetArrayLength(kTxtEntries), *message));
1634*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtDataLength == message->GetLength());
1635*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(0, txtData, txtDataLength));
1636*cfb92d14SAndroid Build Coastguard Worker
1637*cfb92d14SAndroid Build Coastguard Worker index = 0;
1638*cfb92d14SAndroid Build Coastguard Worker for (const EncodedTxtData &encodedData : kEncodedTxtData)
1639*cfb92d14SAndroid Build Coastguard Worker {
1640*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&txtData[index], encodedData.mData, encodedData.mLength) == 0);
1641*cfb92d14SAndroid Build Coastguard Worker index += encodedData.mLength;
1642*cfb92d14SAndroid Build Coastguard Worker }
1643*cfb92d14SAndroid Build Coastguard Worker
1644*cfb92d14SAndroid Build Coastguard Worker iterator.Init(txtData, txtDataLength);
1645*cfb92d14SAndroid Build Coastguard Worker
1646*cfb92d14SAndroid Build Coastguard Worker for (const Dns::TxtEntry &expectedTxtEntry : kTxtEntries)
1647*cfb92d14SAndroid Build Coastguard Worker {
1648*cfb92d14SAndroid Build Coastguard Worker uint8_t expectedKeyLength = static_cast<uint8_t>(strlen(expectedTxtEntry.mKey));
1649*cfb92d14SAndroid Build Coastguard Worker
1650*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(iterator.GetNextEntry(txtEntry), "TxtEntry::GetNextEntry() failed");
1651*cfb92d14SAndroid Build Coastguard Worker printf("key:\"%s\" valueLen:%d\n", txtEntry.mKey != nullptr ? txtEntry.mKey : "(null)", txtEntry.mValueLength);
1652*cfb92d14SAndroid Build Coastguard Worker
1653*cfb92d14SAndroid Build Coastguard Worker if (expectedKeyLength > Dns::TxtEntry::kMaxIterKeyLength)
1654*cfb92d14SAndroid Build Coastguard Worker {
1655*cfb92d14SAndroid Build Coastguard Worker // When the key is longer than recommended max key length,
1656*cfb92d14SAndroid Build Coastguard Worker // the full encoded string is returned in `mValue` and
1657*cfb92d14SAndroid Build Coastguard Worker // `mValueLength` and `mKey` should be set to `nullptr`.
1658*cfb92d14SAndroid Build Coastguard Worker
1659*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtEntry.mKey == nullptr, "TxtEntry key does not match expected value for long key");
1660*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtEntry.mValueLength == expectedKeyLength + expectedTxtEntry.mValueLength + sizeof(char),
1661*cfb92d14SAndroid Build Coastguard Worker "TxtEntry value length is incorrect for long key");
1662*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(txtEntry.mValue, expectedTxtEntry.mKey, expectedKeyLength) == 0);
1663*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtEntry.mValue[expectedKeyLength] == static_cast<uint8_t>('='));
1664*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&txtEntry.mValue[expectedKeyLength + sizeof(uint8_t)], expectedTxtEntry.mValue,
1665*cfb92d14SAndroid Build Coastguard Worker expectedTxtEntry.mValueLength) == 0);
1666*cfb92d14SAndroid Build Coastguard Worker continue;
1667*cfb92d14SAndroid Build Coastguard Worker }
1668*cfb92d14SAndroid Build Coastguard Worker
1669*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(strcmp(txtEntry.mKey, expectedTxtEntry.mKey) == 0);
1670*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtEntry.mValueLength == expectedTxtEntry.mValueLength);
1671*cfb92d14SAndroid Build Coastguard Worker
1672*cfb92d14SAndroid Build Coastguard Worker if (txtEntry.mValueLength != 0)
1673*cfb92d14SAndroid Build Coastguard Worker {
1674*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(txtEntry.mValue, expectedTxtEntry.mValue, txtEntry.mValueLength) == 0);
1675*cfb92d14SAndroid Build Coastguard Worker }
1676*cfb92d14SAndroid Build Coastguard Worker else
1677*cfb92d14SAndroid Build Coastguard Worker {
1678*cfb92d14SAndroid Build Coastguard Worker // Ensure both `txtEntry.mKey` and `expectedTxtEntry.mKey` are
1679*cfb92d14SAndroid Build Coastguard Worker // null or both are non-null (for boolean or empty keys).
1680*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((txtEntry.mKey == nullptr) == (expectedTxtEntry.mKey == nullptr),
1681*cfb92d14SAndroid Build Coastguard Worker "TxtEntry value does not match expected value for bool or empty key");
1682*cfb92d14SAndroid Build Coastguard Worker }
1683*cfb92d14SAndroid Build Coastguard Worker }
1684*cfb92d14SAndroid Build Coastguard Worker
1685*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iterator.GetNextEntry(txtEntry) == kErrorNotFound, "GetNextEntry() returned unexpected entry");
1686*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iterator.GetNextEntry(txtEntry) == kErrorNotFound, "GetNextEntry() succeeded after done");
1687*cfb92d14SAndroid Build Coastguard Worker
1688*cfb92d14SAndroid Build Coastguard Worker // Verify `AppendEntries()` correctly rejecting invalid key
1689*cfb92d14SAndroid Build Coastguard Worker txtEntry.mValue = kValue1;
1690*cfb92d14SAndroid Build Coastguard Worker txtEntry.mValueLength = sizeof(kValue1);
1691*cfb92d14SAndroid Build Coastguard Worker txtEntry.mKey = kShortKey;
1692*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Dns::TxtEntry::AppendEntries(&txtEntry, 1, *message) == kErrorInvalidArgs,
1693*cfb92d14SAndroid Build Coastguard Worker "AppendEntries() did not fail with invalid key");
1694*cfb92d14SAndroid Build Coastguard Worker
1695*cfb92d14SAndroid Build Coastguard Worker // Verify appending empty txt data
1696*cfb92d14SAndroid Build Coastguard Worker
1697*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1698*cfb92d14SAndroid Build Coastguard Worker
1699*cfb92d14SAndroid Build Coastguard Worker data.Init(txtData, sizeof(txtData));
1700*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::TxtEntry::AppendEntries(nullptr, 0, data), "AppendEntries() failed with empty array");
1701*cfb92d14SAndroid Build Coastguard Worker txtDataLength = data.GetLength();
1702*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtDataLength == sizeof(uint8_t), "Data length is incorrect with empty array");
1703*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtData[0] == 0, "Data is invalid with empty array");
1704*cfb92d14SAndroid Build Coastguard Worker
1705*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::TxtEntry::AppendEntries(nullptr, 0, *message), "AppendEntries() failed with empty array");
1706*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == txtDataLength);
1707*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(0, txtData, txtDataLength));
1708*cfb92d14SAndroid Build Coastguard Worker
1709*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(0));
1710*cfb92d14SAndroid Build Coastguard Worker txtEntry.mKey = nullptr;
1711*cfb92d14SAndroid Build Coastguard Worker txtEntry.mValue = nullptr;
1712*cfb92d14SAndroid Build Coastguard Worker txtEntry.mValueLength = 0;
1713*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Dns::TxtEntry::AppendEntries(&txtEntry, 1, *message), "AppendEntries() failed with empty entry");
1714*cfb92d14SAndroid Build Coastguard Worker txtDataLength = message->GetLength();
1715*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtDataLength == sizeof(uint8_t), "Data length is incorrect with empty entry");
1716*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, txtData, txtDataLength), "Failed to read txt data from message");
1717*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(txtData[0] == 0, "Data is invalid with empty entry");
1718*cfb92d14SAndroid Build Coastguard Worker
1719*cfb92d14SAndroid Build Coastguard Worker // Verify `Iterator` behavior with invalid txt data.
1720*cfb92d14SAndroid Build Coastguard Worker
1721*cfb92d14SAndroid Build Coastguard Worker iterator.Init(kInvalidEncodedTxt1, sizeof(kInvalidEncodedTxt1));
1722*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iterator.GetNextEntry(txtEntry) == kErrorParse, "GetNextEntry() did not fail with invalid data");
1723*cfb92d14SAndroid Build Coastguard Worker
1724*cfb92d14SAndroid Build Coastguard Worker // Verify `GetNextEntry()` correctly skipping over empty strings and
1725*cfb92d14SAndroid Build Coastguard Worker // strings starting with '=' (missing key) in encoded txt.
1726*cfb92d14SAndroid Build Coastguard Worker //
1727*cfb92d14SAndroid Build Coastguard Worker // kSpecialEncodedTxt:
1728*cfb92d14SAndroid Build Coastguard Worker // { 0, 3, 'A', '=', 'B', 2, '=', 'C', 3, 'D', '=', 'E', 3, '=', '1', '2' }
1729*cfb92d14SAndroid Build Coastguard Worker
1730*cfb92d14SAndroid Build Coastguard Worker iterator.Init(kSpecialEncodedTxt, sizeof(kSpecialEncodedTxt));
1731*cfb92d14SAndroid Build Coastguard Worker
1732*cfb92d14SAndroid Build Coastguard Worker // We should get "A=B` (or key="A", and value="B")
1733*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(iterator.GetNextEntry(txtEntry), "GetNextEntry() failed");
1734*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((txtEntry.mKey[0] == 'A') && (txtEntry.mKey[1] == '\0'), "GetNextEntry() got incorrect key");
1735*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((txtEntry.mValueLength == 1) && (txtEntry.mValue[0] == 'B'), "GetNextEntry() got incorrect value");
1736*cfb92d14SAndroid Build Coastguard Worker
1737*cfb92d14SAndroid Build Coastguard Worker // We should get "D=E` (or key="D", and value="E")
1738*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(iterator.GetNextEntry(txtEntry), "GetNextEntry() failed");
1739*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((txtEntry.mKey[0] == 'D') && (txtEntry.mKey[1] == '\0'), "GetNextEntry() got incorrect key");
1740*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((txtEntry.mValueLength == 1) && (txtEntry.mValue[0] == 'E'), "GetNextEntry() got incorrect value");
1741*cfb92d14SAndroid Build Coastguard Worker
1742*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iterator.GetNextEntry(txtEntry) == kErrorNotFound, "GetNextEntry() returned extra entry");
1743*cfb92d14SAndroid Build Coastguard Worker
1744*cfb92d14SAndroid Build Coastguard Worker message->Free();
1745*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
1746*cfb92d14SAndroid Build Coastguard Worker }
1747*cfb92d14SAndroid Build Coastguard Worker
1748*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
1749*cfb92d14SAndroid Build Coastguard Worker
main(void)1750*cfb92d14SAndroid Build Coastguard Worker int main(void)
1751*cfb92d14SAndroid Build Coastguard Worker {
1752*cfb92d14SAndroid Build Coastguard Worker ot::TestDnsName();
1753*cfb92d14SAndroid Build Coastguard Worker ot::TestDnsCompressedName();
1754*cfb92d14SAndroid Build Coastguard Worker ot::TestHeaderAndResourceRecords();
1755*cfb92d14SAndroid Build Coastguard Worker ot::TestDnsTxtEntry();
1756*cfb92d14SAndroid Build Coastguard Worker
1757*cfb92d14SAndroid Build Coastguard Worker printf("All tests passed\n");
1758*cfb92d14SAndroid Build Coastguard Worker return 0;
1759*cfb92d14SAndroid Build Coastguard Worker }
1760