[srp-server] allow service instance label with dot character (#9198)

This commit updates the `Srp::Server` class to correctly handle the
case where a service is registered with a dot character in its
service instance name. The first label in a service instance name is
intended as a user-friendly name and can contain dot characters
(it has fewer restrictions than other labels in a DNS name).

In particular, this commit contains the following changes:
- The `PtrRecords::ReadPtrName()` method is used in `Srp::Server` to
  read and validate the first label and the rest of the labels
  separately. This also validates the format of the parsed PTR
  record.
- The `Service::Description` class now remembers the instance label in
  addition to the full instance name. This allows the instance label
  to be easily retrieved.
- The `Dns::Name::ReadName()` method is updated to only verify that
  the labels after the first label do not contain any dot characters.
  This allows it to be used to read instance service names.
- The tests are updated to validate the behavior of the SRP server
  when the instance label contains a dot character.
This commit is contained in:
Abtin Keshavarzian
2023-06-26 12:55:45 -07:00
committed by GitHub
parent 97e9f58026
commit 0cc1de7b5a
6 changed files with 66 additions and 33 deletions
+14 -9
View File
@@ -478,6 +478,7 @@ void TestDnsCompressedName(void)
static const char kExpectedReadName1[] = "F.ISI.ARPA.";
static const char kExpectedReadName2[] = "FOO.F.ISI.ARPA.";
static const char kExpectedReadName3[] = "ISI.ARPA.";
static const char kExpectedReadName4[] = "Human.Readable.F.ISI.ARPA.";
static const char kBadName[] = "bad.name";
@@ -745,10 +746,12 @@ void TestDnsCompressedName(void)
VerifyOrQuit(labelLength == strlen(label), "Name::ReadLabel() returned incorrect label length");
}
// `ReadName()` for name-4 should fails due to first label containing dot char.
// `ReadName()` for name-4 should still succeed since only the first label contains dot char
offset = name4Offset;
VerifyOrQuit(Dns::Name::ReadName(*message, offset, name, sizeof(name)) == kErrorParse,
"Name::ReadName() did not fail with invalid label");
SuccessOrQuit(Dns::Name::ReadName(*message, offset, name, sizeof(name)));
printf("Read name =\"%s\"\n", name);
VerifyOrQuit(strcmp(name, kExpectedReadName4) == 0, "Name::ReadName() did not return expected name");
VerifyOrQuit(offset == name4Offset + kName4EncodedSize, "Name::ParseName() returned incorrect offset");
offset = name4Offset;
@@ -826,9 +829,9 @@ void TestHeaderAndResourceRecords(void)
const char kServiceLabels[] = "_service._udp";
const char kServiceName[] = "_service._udp.example.com.";
const char kInstance1Label[] = "inst1";
const char kInstance2Label[] = "instance2";
const char kInstance2Label[] = "instance.2"; // Instance label includes dot '.' character.
const char kInstance1Name[] = "inst1._service._udp.example.com.";
const char kInstance2Name[] = "instance2._service._udp.example.com.";
const char kInstance2Name[] = "instance.2._service._udp.example.com.";
const char kHostName[] = "host.example.com.";
const uint8_t kTxtData[] = {9, 'k', 'e', 'y', '=', 'v', 'a', 'l', 'u', 'e', 0};
const char kHostAddress[] = "fd00::abcd:";
@@ -988,16 +991,18 @@ void TestHeaderAndResourceRecords(void)
VerifyOrQuit(offset == answerSectionOffset, "answer section offset is incorrect");
for (const char *instanceName : kInstanceNames)
for (const char *instanceLabel : kInstanceLabels)
{
SuccessOrQuit(Dns::Name::CompareName(*message, offset, kServiceName));
SuccessOrQuit(Dns::ResourceRecord::ReadRecord(*message, offset, ptrRecord));
VerifyOrQuit(ptrRecord.GetTtl() == kTtl, "Read PTR is incorrect");
SuccessOrQuit(ptrRecord.ReadPtrName(*message, offset, name, sizeof(name)));
VerifyOrQuit(strcmp(name, instanceName) == 0, "Inst1 name is incorrect");
SuccessOrQuit(ptrRecord.ReadPtrName(*message, offset, label, sizeof(label), name, sizeof(name)));
VerifyOrQuit(strcmp(label, instanceLabel) == 0, "Inst label is incorrect");
VerifyOrQuit(strcmp(name, kServiceName) == 0);
printf(" \"%s\" PTR %u %d \"%s\"\n", kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength(), name);
printf(" \"%s\" PTR %u %d \"%s.%s\"\n", kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength(), label,
name);
}
VerifyOrQuit(offset == additionalSectionOffset, "offset is incorrect after answer section parse");
+1 -1
View File
@@ -287,7 +287,7 @@ static const char kHostName[] = "myhost";
void PrepareService1(Srp::Client::Service &aService)
{
static const char kServiceName[] = "_srv._udp";
static const char kInstanceLabel[] = "srv-instance";
static const char kInstanceLabel[] = "srv.instance";
static const char kSub1[] = "_sub1";
static const char kSub2[] = "_V1234567";
static const char kSub3[] = "_XYZWS";