Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[multicast_dns] Allow decode of binary encoded TXT #5856

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ajhemphill91
Copy link

@ajhemphill91 ajhemphill91 commented Jan 10, 2024

Follow up on flutter/flutter#141218. Added a unit test with a binary-encoded payload.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Copy link

google-cla bot commented Jan 10, 2024

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ajhemphill91
Copy link
Author

ajhemphill91 commented Jan 10, 2024

Side note, the decoding algorithm for TXT data is still not exactly in spec (see RFC6763 6.3-6.5).

In particular:

DNS-SD TXT record strings
beginning with an '=' character (i.e., the key is missing) MUST be
silently ignored.

The characters of a key MUST be printable US-ASCII values (0x20-0x7E)
[RFC20], excluding '=' (0x3D).

These don't matter to me too much at the present time (and I have made no changes in this PR regarding them). It does look like the openthread border router's implementation has these restrictions on the '=' character within the key.

@stuartmorgan
Copy link
Contributor

From triage: ping @dnfield on this review

@stuartmorgan stuartmorgan requested review from jmagman and removed request for dnfield April 9, 2024 20:09
@@ -338,11 338,15 @@ class TxtResourceRecord extends ResourceRecord {
const TxtResourceRecord(
String name,
int validUntil, {
required this.text,
required this.attrs,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay in this review.

I believe this would be a breaking change to TxtResourceRecord?

How about a new named constructor:

  TxtResourceRecord.attributes(
    String name,
    int validUntil, {
    required List<String> attributes,
  }) : this(name, validUntil, text: attributes.join('\n'));

Also total nit but attributes instead of attrs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A way to do this without it being a breaking change would be to:

  1. Make text nullable and mark it deprecated.
  2. Add attrs as nullable.
  3. Throw if (a) both or (b) neither are null.

After the deprecation period, mark attrs as non-nullable and remove text.

If very few packages are relying on this, then it might not be worth the effort.

@jmagman
Copy link
Member

jmagman commented May 9, 2024

Hi @ajhemphill91, have you been able to circle back to the requested change for the named constructor? Appreciate your contribution!

@ajhemphill91
Copy link
Author

Sorry for the delay, I have been on another project recently. If you do have a preference to keep the original constructor (and thus the original final String text property) for API stability, your suggested changes sound good. Internally, this constructor is only referenced once in packet.dart and then in the unit tests which are updated by this commit.

The text property as a String is not valid since it represents a list of encoded strings which are treated as binary information. Basically it mutates the record by adding the \n characters.

Actually now that I am looking at it, encodeResponseRecord ought to fail to produce correct results too since the record is mutated by the text property. However it looks as though this property is never referenced anywhere.

@stuartmorgan
Copy link
Contributor

From triage: @ajhemphill91 Are you still planning on updating this PR?

@ajhemphill91
Copy link
Author

I can apply the nit, but changing back to a named constructor that joins the records with a newline nullifies this PR in the first place. What would you like me to do?

@jmagman
Copy link
Member

jmagman commented Jun 4, 2024

Sorry, didn't realize this PR was waiting for my response.

but changing back to a named constructor that joins the records with a newline nullifies this PR in the first place

Hm, yeah I can't think of a way to do this without something unpleasant like a text.split('\n')

  TxtResourceRecord(
    String name,
    int validUntil, {
    required this.text,
  })  : attrs = text.split('\n'),
        super(ResourceRecordType.text, name, validUntil);

  TxtResourceRecord.attributes(
    String name,
    int validUntil, {
    required this.attrs,
  })  : text = attrs.join('\n'),
        super(ResourceRecordType.text, name, validUntil);

Adding @cbracken for his opinion here. Ideally this could be done without a breaking change.

@jmagman jmagman requested a review from cbracken June 4, 2024 23:17
@stuartmorgan
Copy link
Contributor

I looked at the usage graph for multicast_dns, and very few published packages rely on it, so a breaking change won't be particularly disruptive (since the chances of a version incompatibility in multiple dependencies is very low). Given that, and that it doesn't seem like we can correctly populate the attributes with the existing constructor, I think doing a breaking change here is fine. Especially since updating to the new major version is likely to require test-only changes at most.

@stuartmorgan
Copy link
Contributor

@ajhemphill91 I've re-added the checklist from the template to the PR description; in the future please don't remove it. This PR is missing several required steps (notably for this discussion, a version change).

@ajhemphill91
Copy link
Author

Per the versioning guide should I then update the pubspec.yaml version to 0.4.0? I can take care of that and the CHANGELOG.md if everyone is okay with the breaking change.

@stuartmorgan
Copy link
Contributor

@jmagman Are you okay with the breaking change?

@jmagman
Copy link
Member

jmagman commented Jul 9, 2024

@jmagman Are you okay with the breaking change?

LGTM, I can't remember if this will impact the tool but it would be easy to fix up

Copy link
Member

@cbracken cbracken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine to me. Suggestion on a non-breaking way to do this in my comment above.

@@ -338,11 338,15 @@ class TxtResourceRecord extends ResourceRecord {
const TxtResourceRecord(
String name,
int validUntil, {
required this.text,
required this.attrs,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A way to do this without it being a breaking change would be to:

  1. Make text nullable and mark it deprecated.
  2. Add attrs as nullable.
  3. Throw if (a) both or (b) neither are null.

After the deprecation period, mark attrs as non-nullable and remove text.

If very few packages are relying on this, then it might not be worth the effort.

@cbracken
Copy link
Member

@ajhemphill91 Looks like Dart formatting and CHANGELOG format checks are failing. See the log here for details:
https://ci.chromium.org/ui/p/flutter/builders/try/Linux repo_checks/4671/overview

Once those are done, I leave it up to you as to whether you want to do the multi-step dance to go through the deprecation, then breaking change removal, or just go straight to the breaking change and land this as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants