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

Draft 02: Describe Nil/Max UUID in variant table #16

Closed
ben221199 opened this issue Oct 21, 2022 · 14 comments
Closed

Draft 02: Describe Nil/Max UUID in variant table #16

ben221199 opened this issue Oct 21, 2022 · 14 comments

Comments

@ben221199
Copy link

At the moment, the Nil-UUID is part of variant 0 and by that definition reserved. Variant 0 uses AF_UNSPEC in that case.

However, the range of the Omni-UUID isn't reserved yet. This issue suggests to reserve a variant of the Omni-UUID. I would suggest to only reserve the 0xFF variant. Why? I will explain.

In the early days of UUID, there was no such thing as variants. There was only "family". This family field consisted of only one single byte, so it ranged from 0 to 255. In modern days, this is the same byte as where the variant byte is in. With this information, the new variant table will be this:

Msb0 Msb1 Msb2 As Byte Values Description
0 * * 0b0******* From 0 to 127 Reserved, NCS backward compatibility.
1 0 * 0b10****** From 128 to 191 The variant specified in this document.
1 1 0 0b110***** From 192 to 223 Reserved, Microsoft Corporation backward compatibility
1 1 1 0b111*****
---
0b11111111
From 224 to 254
---
Only 255
Reserved for future definition.
---
Omni-UUID variant

Handling the variant/family like this, it has at least 2 advantages:

  • It reserves a variant for the Omni-UUID, so that there will be no conflicts when a new variant will be specificed.
  • You clearly see that there are 31 variant slots open for definition (32 including Omni-UUID variant).

This doesn't mean that Variant 255 always should have all bits set to 1. It only reserves the range the Omni-UUID is in. I also think it is important to add this variant in this specification, because this specification defines the Omni-UUID itself.

@kyzer-davis
Copy link
Collaborator

Seems logical enough to me. I will slate it for IETF 115 discussion in addition to cross posting to the mailing group.

@LiosK
Copy link
Contributor

LiosK commented Nov 2, 2022

Makes sense. I agree some clarification is necessary because Table 1 looks to conflict with Max UUID, but by the way, do we need to limit the variant field to one byte rather than the remaining 64 bits? Even after our great-great-grandchildren consume 0b1111_1110, they can still define 0b1111_1111_0. The variant field is variable-length by its nature, so perhaps it is more helpful to describe the 10 technique explicitly. I haven't come up with a good idea to do this, but how about something like this?

Msb0 Msb1 Msb2 Msb3 Description
0 x x x Reserved, NCS backward compatibility.
1 0 x x The variant specified in this document.
1 1 0 x Reserved, Microsoft Corporation backward compatibility
1 1 1 0 Reserved for a future variant.
1 1 1 1 Reserved for future variants and Max UUID.

Or this?

Msb0 Msb1 Msb2 Description
0 x x Reserved, NCS backward compatibility.
1 0 x The variant specified in this document.
1 1 0 Reserved, Microsoft Corporation backward compatibility
1 1 1 Reserved for future variants and Max UUID.

@LiosK
Copy link
Contributor

LiosK commented Nov 2, 2022

We could also say "Reserved for the next future variant." for 0b1110.

@ben221199
Copy link
Author

The variant field is variable-length by its nature, so perhaps it is more helpful to describe the 10 technique explicitly.

This is not fully correct. Forget about how the table is in RFC 4122. In the good old Apollo Computer days, there was a family field that was exactly 8 bits. Because only 13 families where used back then, the makers of RFC 4122 decided when starting with a 0-bit, it was variant 0 and defined families, and when starting with a 1-bit, it was another variant.

Making the variant field variable length, doesn't make any sense. It was defined on the same location as the family field on purpose. I would almost rather say: the variant field IS the family field.


What I think should be done? Well, I would recommend to redefine all variants to their 8-bit format, where x is a "don't care", so variant 0 becomes 0xxxxxxx, variant 10 becomes 10xxxxxx and variant 110 becomes 110xxxxx. Why is this useful? Because you can assign ranges to it (see column 'Values' in my table). Instead of checking seperate bits, you just read the family byte, check the ranges, and you know the variant. Using 8-bit notation is also easier to understand and better to use in some IANA registry.


do we need to limit the variant field to one byte rather than the remaining 64 bits?

Look at what happened to 10xxxxxx. This variant supports multiple versions. If you are afraid of running out of variants in the future, just reserve one variant now using the 8-bit notation and write an RFC that defines how your subversioning works, just like variant 1 in RFC 4122. Problem solved.

@ben221199
Copy link
Author

So this...

Msb0 Msb1 Msb2 Description
0 x x Reserved, NCS backward compatibility.
1 0 x The variant specified in this document.
1 1 0 Reserved, Microsoft Corporation backward compatibility
1 1 1 Reserved for future variants and Max UUID.

...should become this...

Msb0 Msb1 Msb2 Msb3 Msb4 Msb5 Msb6 Msb7 Description Range
0 x x x x x x x Reserved, NCS backward compatibility. From 0 to 127
1 0 x x x x x x The variant specified in this document. From 128 to 191
1 1 0 x x x x x Reserved, Microsoft Corporation backward compatibility From 192 to 223
1 1 1 x x x x x This was Reserved for future definition. in RFC 4122. Now we can reserve variant 224 to 254 for new formats and reserve 255 for Omni-UUID. This gives us space for 31 new variants. If you are afraid of running out of these variants soon, define one now and write an RFC about it, just like how variant 128-191 works with versions. From 224 to 255

...in my opinion.

@LiosK
Copy link
Contributor

LiosK commented Nov 2, 2022

We can just forget about the family field because, as long as Msb0 is set to 1, no ID will collide with 0b0 variant values. Technically, the 0b1 authors could have done whatever they liked using the remaining 63 bits, but they generously gave up Msb1 so the future authors could use 0b11. We should pay it forward; those who claim 0b111 should stick to 0b1110 and reserve 0b1111 for future authors. Similarly, 0b1111 should reserve 0b1111_1, 0b1111_1 should reserve 0b1111_11, 0b1111_11 should reserve 0b1111_111, and so on. Accordingly, the table should look like this in full:

Msb0 Msb1 Msb2 Msb3 Msb4 Msb5 Msb6 ... Msb63 Msb64 Description
0 x x x x x x ... x x Reserved, NCS backward compatibility.
1 0 x x x x x ... x x The variant specified in this document.
1 1 0 x x x x ... x x Reserved, Microsoft Corporation backward compatibility
1 1 1 0 x x x ... x x Reserved for the 1st future variant.
1 1 1 1 0 x x ... x x Reserved for the 2nd future variant.
1 1 1 1 1 0 x ... x x Reserved for the 3rd future variant.
1 1 1 1 1 1 0 ... x x Reserved for the 4th future variant.
... ... ... ... ... ... ... ... ... ... ...
1 1 1 1 1 1 1 ... 1 0 Reserved for the last future variant.
1 1 1 1 1 1 1 ... 1 1 Reserved for Max UUID.

@ben221199
Copy link
Author

I don't think this is useful. First, we don't need 18446744073709551616 variants, or in this case 64 variants (what actually isn't very different from 32, so I don't see a reason for having 64), I think we could better use this amount of possibilities for identifying objects, not variants. Second, maybe someone don't want have subversioning on the bytes directly after the family field, maybe he wants is at the beginning of the UUID or somewhere else.

@LiosK
Copy link
Contributor

LiosK commented Nov 2, 2022

Perhaps, at this stage, we don't need to say in the RFC what the 0b111 taker should do. So, just keeping Table 1 as is or the following should be enough:

Msb0 Msb1 Msb2 Description
0 x x Reserved, NCS backward compatibility.
1 0 x The variant specified in this document.
1 1 0 Reserved, Microsoft Corporation backward compatibility
1 1 1 Reserved for future variants and Max UUID.

It doesn't really make sense to reserve one byte and order the next variant author to use 0b1110_0000. It wastes precious five bits for forward compatibility, which is too costly in my opinion. A new variant will be rarely necessary; the 0b10 variant is sufficient unless there is a serious need to remove the ver field, so we don't need to declare a large var space right now. Let's just leave it to the 0b111 takers like: uuid6/uuid6-ietf-draft#26

@ben221199
Copy link
Author

I think your last row in the table is a very bad thing to do. Also, you contradict yourself by saying that my way is too costly, but we also don't need many variants. Note that version can only hold 16 values, where half of it is already taken. Also, uuid6/uuid6-ietf-draft#26 is out of scope.

@LiosK
Copy link
Contributor

LiosK commented Nov 4, 2022

I think your last row in the table is a very bad thing to do.

Can you please elaborate on this point?

Also, you contradict yourself by saying that my way is too costly, but we also don't need many variants.

Not contradictory. Because we don't need many variants, reserving one byte for var is too costly.

Note that version can only hold 16 values, where half of it is already taken. Also, uuid6/uuid6-ietf-draft#26 is out of scope.

I'm afraid you are confusing versions and variants. Versions are specific to the 0b10 variant and have nothing to do with the future variants. If the future 0b111 authors believe they need sub-variants, they will allocate another version bits somewhere in the 128-bit space. If not, the version field will simply go away and the four bits will be utilized differently. We should let them decide, as we can't foresee the future.

On the other hand, if the future authors are considerate enough of the future of UUID spec, they will likely take the 0b1110 variant so the next future authors can take 0b1111, just as uuid6/uuid6-ietf-draft#26 tried to. E variant is out of scope, but the discussion clearly demonstrates how the var field can be utilized in the future. Similarly, 0b1111 takers are likely to reserve 0b1111_1, 0b1111_1 takers to reserve 0b1111_11, and so on. In this way, the var field can be variable-length, which might grows over many decades. I don't mean we should reserve 64 variants right now.

I now think it's a good idea to add one paragraph below Table 1 stating the above intention to guide future authors like:

Future RFC authors who consume the reserved "111" variant are encouraged to (or, simply, SHOULD) define the "1110" variant and reserve the "1111" variant so that the next future authors can extend the UUID specification using the "1111" variant as well as the new variant does not conflict with the Max UUID.

We can only encourage (but not enforce) this rule because, as long as var starts with 0b111, the future authors can do whatever they want without conflicting with the old standards. We cannot enforce the "one byte var" rule either for the same reason.

@kyzer-davis
Copy link
Collaborator

kyzer-davis commented Jan 20, 2023

Repeating my comment from The January IETF interim meeting:
Are we over engineering a solution?

This reads like we just want to clarify within the table that Nil/Max (omni) are present in the variant ranges.

Could we not update the table to say:
Reserved, NCS backward compatibility and includes Nil UUID <insert section reference>
Reserved for future definition and includes Max UUID <insert section reference>

@ben221199
Copy link
Author

Seems to me a reasonable solution for now. It reserves the range where Omni-UUID is in for later definition, but also already tells to take into account having a variant for it in the future.

One addition: It seems the RFC at the moment will only documentate variant 1 (and its subversions). Maybe it is also good to documentate variant 0 (and its subfamilies). Because variant 0 family 0 is af_unspec, it is compatible with old specifications to documentate variant 0 and also include Nil-UUID:
image

 *
 * Internal structure of variant #0 UUIDs
 *
 * The first 6 octets are the number of 4 usec units of time that have
 * passed since 1/1/80 0000 GMT.  The next 2 octets are reserved for
 * future use.  The next octet is an address family.  The next 7 octets
 * are a host ID in the form allowed by the specified address family.
 *
 * Note that while the family field (octet 8) was originally conceived
 * of as being able to hold values in the range [0..255], only [0..13]
 * were ever used.  Thus, the 2 MSB of this field are always 0 and are
 * used to distinguish old and current UUID forms.
 *
 * +--------------------------------------------------------------+
 * |                    high 32 bits of time                      |  0-3  .time_high
 * +-------------------------------+-------------------------------
 * |     low 16 bits of time       |  4-5               .time_low
 * +-------+-----------------------+
 * |         reserved              |  6-7               .reserved
 * +---------------+---------------+
 * |    family     |   8                                .family
 * +---------------+----------...-----+
 * |            node ID               |  9-16           .node
 * +--------------------------...-----+
 *
 */

Source: https://opensource.apple.com/source/CF/CF-299.35/Base.subproj/uuid.c.auto.html

So, for Nil-UUID:

  • All time bits are zero
  • All reserved bits are zero by definition
  • All family bits are zero. The first bit tells us it is variant 0; in combination with the other 7 bits, we also know the family: AF_UNSPEC. Because the family is UNSPEC, we don't have to follow any family format rules.
  • All node ID bits are zero.

Then, we can change the description text for variant zero to:
Apollo NCS format [Section x.x], including Nil-UUID [Section y.y].

@kyzer-davis
Copy link
Collaborator

@ben221199, maybe I can sneak Variant 0 and its sub-families into an appendix or I could link that source exactly as a reference.
I would hate to add technical information we are not fully in control of. Basically treat it like UUIDv2m "out of our control go to this doc to read about it." and insert the source.

@kyzer-davis kyzer-davis changed the title Reserve variant for Omni-UUID (Max-UUID) Draft 02: Describe Nil/Max UUID in variant table Jan 23, 2023
@ben221199
Copy link
Author

I think an appendix would be okay for now. In that case, at least the variant is included in the RFC, so no linking to sources that can disappear in the future, but not part of the main specification. I'm cool with that.

kyzer-davis added a commit that referenced this issue Jan 31, 2023
kyzer-davis added a commit that referenced this issue Feb 16, 2023
- Describe Nil/Max UUID in variant table #16
- Further Clarify that non-descript node IDs are the preferred method in distributed UUID Generation #49
- Appendix B, consistent naming #55
- Remove duplicate ABNF from IANA considerations #56
- Monotonic Error Checking missing newline #57
- More Security Considerations Randomness #26
- SHA265 UUID Generation #50
- Expand multiplexed fields within v1 and v6 bit definitions # 43
- Clean up text in UUIDs that Do Not Identify the Host #61
- Revise UUID Generator States section #47
- Expand upon why unix epoch rollover is not a problem #44
- Delete Sample Code Appendix #62
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants