Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Review of main#5

Open
Frando wants to merge 55 commits intoemptyfrom
review
Open

Review of main#5
Frando wants to merge 55 commits intoemptyfrom
review

Conversation

@Frando
Copy link
Copy Markdown
Member

@Frando Frando commented Mar 28, 2024

This contains the full diff of the empty repo against main for review purposes.

inc!(Metrics, http_requests_error);
}
//
// let labels = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is copypasted from the axum-telemetry example. opentelemetry and prometheus can associate counters and histograms to labels, which allows to e.g. see how many PUT vs GET requests occured, or the request durations for a specific path, etc. iroh-metrics does not support this at the moment. cc @Arqu - maybe you know more what we are missing to support this? Not a high priority atm I think, but would be nice to have also for metrics in iroh (e.g. attach document id to doc metrics to thus track transfer etc per doc in addition to global),

Copy link
Copy Markdown

@dignifiedquire dignifiedquire left a comment

Choose a reason for hiding this comment

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

looks good for the most part, left some code style nits

@Nuhvi
Copy link
Copy Markdown

Nuhvi commented Apr 2, 2024

WDYT?

As far as I understand from researching this, Variant C is the most idiomatic, and I would definitely encourage it despite the size overhead because:

  1. I found no convention for how to add multiple attributes in the same TXT, some use ; separators, but really I never saw multiple attributes in the wild yet.
  2. TXT records are made of smaller parts that have 255 bytes limit, so if you make a longer TXT record, it will be split into multiple of these strings, and now you have to cross your fingers that all clients know how to join these and then parse attributes (see long_attributes, which ... ehm I added to simple-dns when I wanted to do Variant B with lots of data, so no guarantee that others will do the same), really not worth it.

@rklaehn
Copy link
Copy Markdown
Contributor

rklaehn commented Apr 2, 2024

"relay=https://derp.io",
"addr=10.0.0.2:3033",
"addr=1.2.3.4:3033"

So you are saying we could get into trouble when the total text in the record exceeds 255 bytes? I think that is unlikely to happen. It's just a few addrs and a derp url.

With the less efficient encoding of option C I would worry that we might reach the hard 1000 byte limit of a pkarr record.

}

impl DnsServer {
/// Create a DNS server given some settings, a connection to the DB for DID-by-username lookups
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fix comment

serial: u32,
) -> Result<Self> {
let origins = {
let mut o = Vec::with_capacity(additional_origins.len());
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

should be + 1

@Nuhvi
Copy link
Copy Markdown

Nuhvi commented Apr 3, 2024

"relay=https://derp.io",
"addr=10.0.0.2:3033",
"addr=1.2.3.4:3033"

So you are saying we could get into trouble when the total text in the record exceeds 255 bytes? I think that is unlikely to happen. It's just a few addrs and a derp url.

With the less efficient encoding of option C I would worry that we might reach the hard 1000 byte limit of a pkarr record.

It is your call, now you know the tradeoff. Maybe you don't care about other DNS clients parsing attributes correctly.

@Frando
Copy link
Copy Markdown
Member Author

Frando commented Apr 3, 2024

I did some tests:
For a hypothetical packet with one relay URL, one ipv4 and one ipv6 address (so three attributes in total), the bytes-encoded pkarr SignedPacket has a total size of:
variant B: 267 bytes
variant C: 291 bytes

A difference of 24 bytes. If I add another addr attribute, the difference is 36 bytes. So variant C has an overhead of 12 bytes per attribute. I thought this to be more, because each attribute creates a new record in variant C which includes the z32pubkey in the name. However! DNS supports a compression during encoding, which the simple_dns library used by pkarr applies, and thus identical labels are not repeated!

I also did some more reading:

  • There's RFC 1464 (from 1993!) which describes the attribute format of key=value (with an escaping scheme to allow including = in the key. It does not talk about multiple attributes under a single label, however it specifies that all characters after the =, without escaping, form the value of the attribute; so variant B would not comply to the standard
  • RFC 1464 does not talk about multiple attributes for a common label much, it does however say that A more complex routine could return attributes with multiple values, or several different attributes. which, I think, means that those would need to use either variant C or D to comply with the RFC
  • There's a RFC 5507 which says that the most idiomatic form would be to register a new RRType with IANA, however this is out of scope for us for now, and would need client support.

I also tried to find out how other protocols use DNS TXT records

  • RFC 6764: DNS-SD uses Variant B: Each key/value pair is encoded as its own constituent string within the DNS TXT record, in the form "key=value"
  • Some protocols append all strings in a TXT record to increase size of the value above 255 bytes,, thus would not allow variant B
  • The tool sdget supports both Variant B and Variant C

So I think both variant B and C will work fine for our usecase. I now have a slight tendency towards variant C:

  • 12 bytes overhead per attribute seems acceptable
  • it composes best, because each attribute is independent of others?

@Nuhvi
Copy link
Copy Markdown

Nuhvi commented Apr 3, 2024

Yup, for some reason I took the compression for granted, and yes Pkarr encodes packets compressed, because obviously the 52 characters of the z32 tld can add up pretty quickly.

Thanks for the thorough research confirming my hand wavy suspicion that multiple attributes in a TXT is too dangerous

@rklaehn
Copy link
Copy Markdown
Contributor

rklaehn commented Apr 4, 2024

So I think both variant B and C will work fine for our usecase. I now have a slight tendency towards variant C:

12 bytes is less than I expected. So I guess there is not much difference between B and C. However, not quite sure what the benefit of C is. Either the packet contains the required info or not. What's the benefit of having this in separate attributes? Does this make command line usage more convenient?

@Nuhvi
Copy link
Copy Markdown

Nuhvi commented Apr 4, 2024

@rklaehn only that if you don't control the DNS parser (unlikely but hey if you embrace DNS, embrace it) then staying close to the idiomatic way help parsers out there read attributes better. As Frando mentioned, many parsers will just consider everything after the first = as one value.

@Frando
Copy link
Copy Markdown
Member Author

Frando commented Apr 4, 2024

I started to write a draft for how to document this, see n0-computer/iroh#2149 - let's take the design discussion over there!

@Frando
Copy link
Copy Markdown
Member Author

Frando commented Apr 10, 2024

We're going to move this into the iroh repo. Please take further discussion to n0-computer/iroh#2167

rklaehn pushed a commit to n0-computer/iroh that referenced this pull request Apr 11, 2024
## Description

Imports https://github.com/n0-computer/iroh-dns-server into this repo.

See n0-computer/iroh-dns-server#5 for previous review/discussion.

Now includes an integration smoke test in `iroh-dns-server/src/lib.rs`.

## Notes & open questions

I *think* I addressed most review points that came up in the initial
review. Prominently still open is:

* The `redb` store is used from async context but only exposes a sync
interface (redb default). I think this is fine for medium load. However
for better performance we should reuse transactions, which likely means
we need an actor on a separate thread, as we do in iroh-bytes and
iroh-sync.

## Change checklist

- [ ] Self-review.
- [ ] Documentation updates if relevant.
- [ ] Tests if relevant.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants