RFC 5203

Host Identity Protocol (HIP) Registration Extension

๐Ÿ“… published April 2008, from ietf

Host Identity Protocol (HIP) Registration Extension โœจ

Okay bestie, let's start with the basics ๐ŸŽ€ This is RFC 5203, and it's an Experimental doc from April 2008. The authors are J. Laganier (DoCoMo Euro-Labs), T. Koponen (HIIT), and L. Eggert (Nokia). Its header doesn't list anything it obsoletes or updates, so it's just vibing solo ๐Ÿฆ‹

Status of This Memo ๐Ÿ’…

Lowkey the most important vibe check: this memo defines an Experimental Protocol for the Internet community. It is not an Internet standard of any kind ๐Ÿ™ˆ The authors are literally asking for feedback and ideas to make it better, and distribution is unlimited, so share it with your whole group chat ๐ŸŒˆ

Abstract ๐ŸŒธ

So the big idea is this: the document specifies a registration mechanism for the Host Identity Protocol (HIP). It lets hosts register with services, like HIP rendezvous servers or middleboxes. Main character energy for the whole protocol ๐Ÿ‘‘

1. Introduction โœจ

Okay so this doc is an extension to the Host Identity Protocol (HIP) [RFC5201]. It gives a host a generic way to register with a service. That service could be a HIP rendezvous server [RFC5204] or a middlebox [RFC3234], iykyk ๐Ÿงš

It makes no further assumptions about what kind of service it is. It also doesn't say how to discover that a specific service exists, or how to interact with it after you've registered. Future documents might cover those things, so stay tuned ๐Ÿซถ

Quick BCP 14 check, because the key words are a whole thing here. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. Not me being extra, just being precise ๐Ÿ’–

2. Terminology ๐ŸŽ€

Ngl, this section is the cheat sheet. On top of the terms from the HIP Architecture [RFC4423], the HIP specification [RFC5201], and the HIP Rendezvous Extension [RFC5204], this doc defines these terms:

  • Requester: a HIP node that registers with a HIP registrar to request registration for a service.
  • Registrar: a HIP node offering registration for one or more services.
  • Service: a facility that gives requesters new capabilities or functionalities operating at the HIP layer. Examples include firewalls that support HIP traversal or HIP rendezvous servers.
  • Registration: shared state stored by a requester and a registrar. It lets the requester benefit from one or more HIP services the registrar offers. Each registration has a finite lifetime. Requesters can extend established registrations through re-registration (i.e., perform a refresh) ๐Ÿ”ฅ
  • Registration Type: an identifier for a given service in the registration protocol. For example, the rendezvous service is identified by a specific registration type ๐Ÿฆ‹

3. HIP Registration Extension Overview ๐Ÿงš

Okay this is the big picture. The doc doesn't say how a requester finds out a service is available, or how it locates a registrar. Once a requester has found a registrar, it either starts a HIP base exchange or uses a HIP association it already has with that registrar. In both cases, registrars use extra parameters (defined in the rest of this doc) to announce their quality and to grant or refuse registration. Requesters use matching parameters to register with the service ๐Ÿ’…

Both the registrar and the requester MAY also include extra HIP parameters for the specific registration type involved. Other documents will define those parameters and how they shall be used. The following sections explain how this registration handshake differs from the standard HIP base exchange [RFC5201] ๐Ÿ’œ

3.1. Registrar Announcing Its Ability ๐Ÿ“ฃ

A host that is capable and willing to act as a registrar SHOULD include a REG_INFO parameter in the R1 packets it sends during all base exchanges. If it's temporarily unable to provide services because of transient conditions, it SHOULD include an empty REG_INFO, meaning one with no services listed. If services become available later, it SHOULD send UPDATE packets with the current set of services in a new REG_INFO parameter to all hosts it's associated with ๐ŸŒธ

3.2. Requester Requesting Registration ๐Ÿ™‹โ€โ™€๏ธ

To request registration, a requester builds a matching REG_REQUEST parameter and includes it in an I2 or UPDATE packet sent to the registrar ๐Ÿ“

If the requester has no HIP association with the registrar yet, it SHOULD send the REG_REQUEST at the earliest possibility, which is in the I2 packet. This keeps the number of packets exchanged with the registrar to a minimum โœจ

A registrar MAY end a HIP association that doesn't carry a REG_REQUEST by including a NOTIFY with the type REG_REQUIRED in the R2. In that case, no HIP association gets created between the hosts. The REG_REQUIRED notification error type is 51 ๐Ÿ™ˆ

3.3. Registrar Granting or Refusing Service(s) Registration ๐Ÿ”

Once registration has been requested, the registrar can authenticate the requester using the host identity included in I2. Then it checks whether that host identity is authorized to register for the requested service(s), based on its local policies. The details of this authorization depend on the type of requested service(s) and the registrar's local policies. That's why this document doesn't specify them further ๐Ÿ’–

After authorization, the registrar includes a REG_RESPONSE parameter in its response. That parameter lists the service type(s) the registrar has authorized. It also includes zero or more REG_FAILED parameters, listing service type(s) it hasn't authorized or where registration failed for other reasons. The response is an R2 or an UPDATE message, depending on whether registration was requested during the base exchange or over an existing association. Also, REG_FAILED with a failure type of zero marks the service type(s) that need further credentials to register ๐ŸŽ€

If the registrar needs further authorization and the requester has more credentials, the requester SHOULD try to register again with the service after the HIP association is established. How to establish and verify those credentials is outside this document's scope. Other documents are expected to define it ๐Ÿซถ

Processing a REG_RESPONSE parameter successfully creates registration state at the requester. Similarly, processing a REG_REQUEST parameter successfully creates registration state at the registrar and possibly at the service. Either the requester or the registrar can cancel a registration before it expires. That's useful if the requester no longer needs the services, or if the registrar can't provide them anymore (for example, because its configuration changed) ๐Ÿฆ‹

Here's the first handshake, with no current HIP association:

                 +-----+          I1          +-----+-----+
                 |     |--------------------->|     |  S1 |
                 |     |<---------------------|     |     |
                 |     |  R1(REG_INFO:S1,S2)  |     +-----+
                 | RQ  |                      |  R  |  S2 |
                 |     |    I2(REG_REQ:S1)    |     |     |
                 |     |--------------------->|     +-----+
                 |     |<---------------------|     |  S3 |
                 |     |    R2(REG_RESP:S1)   |     |     |
                 +-----+                      +-----+-----+

A requester (RQ) registers with a registrar (R) of services (S1) and (S2), and it has no current HIP association with that registrar ๐Ÿ‘€

And here's the second one, where the association is already up:

                 +-----+                      +-----+-----+
                 |     |  UPDATE(REG_INFO:S)  |     |     |
                 |     |<---------------------|     |     |
                 | RQ  |--------------------->|  R  |  S  |
                 |     |  UPDATE(REG_REQ:S)   |     |     |
                 |     |  UPDATE(REG_RESP:S)  |     |     |
                 |     |<---------------------|     |     |
                 +-----+                      +-----+-----+

A requester (RQ) registers with a registrar (R) of service (S), and it currently has a HIP association established with that registrar ๐Ÿ’œ

4. Parameter Formats and Processing ๐Ÿ“

This section covers the format and processing of the new parameters the HIP registration extension introduces ๐Ÿงš

4.1. Encoding Registration Lifetimes with Exponents โณ

HIP registration uses an exponential encoding for registration lifetimes. That means 255 different lifetime values, ranging from 4 ms to 178 days, fit into one 8-bit integer field. The lifetime exponent field used throughout this document MUST be interpreted as representing the lifetime value 2^((lifetime - 64)/8) seconds. Math is giving smart, and so is the encoding ๐Ÿค“

4.2. REG_INFO ๐Ÿ“ฃ

This is the REG_INFO parameter layout. Here's how it's laid out:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             Type              |             Length            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Min Lifetime  | Max Lifetime  |  Reg Type #1  |  Reg Type #2  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      ...      |     ...       |  Reg Type #n  |               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    Padding    +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

And here's what each field means:

   Type           930
   Length         Length in octets, excluding Type, Length, and Padding.
   Min Lifetime   Minimum registration lifetime.
   Max Lifetime   Maximum registration lifetime.
   Reg Type       The registration types offered by the registrar.

Other documents will define specific values for registration types. Check out Section 7 for more info ๐Ÿ”

Registrars include this parameter in R1 packets to announce their registration capabilities. The registrar SHOULD include the parameter in UPDATE packets when its service offering changes. HIP_SIGNATURE_2 protects the parameter within the R1 packets, so it's locked in ๐Ÿ”

Part 1 done, bestie ๐Ÿซถ More parts are coming, so stay tuned ๐Ÿ’œ

4.3. REG_REQUEST โœจ

Okay so, this is the parameter the requester sends to say "hey registrar, I'd like to sign up for these services, please!" ๐Ÿ’– It rides along in I2 or UPDATE packets.

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             Type              |             Length            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Lifetime    |  Reg Type #1  |  Reg Type #2  |  Reg Type #3  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      ...      |     ...       |  Reg Type #n  |               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    Padding    +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   Type        932
   Length      Length in octets, excluding Type, Length, and Padding.
   Lifetime    Requested registration lifetime.
   Reg Type    The preferred registration types in order of preference.

Other documents will define specific values for registration types. See Section 7 for more information. ๐Ÿงš

Okay, the main vibe: a requester includes the REG_REQUEST parameter in I2 or UPDATE packets to register with a registrar's service(s). If REG_REQUEST shows up in an UPDATE packet, the registrar MUST NOT modify the registrations of registration types that are not listed in the parameter. ๐Ÿ™…โ€โ™€๏ธ Also, the requester MUST NOT include the parameter unless the registrar's R1 packet or latest received UPDATE packet has contained a REG_INFO parameter with the requested registration types. The registrar has to be ready for it, though: the requester MUST NOT include more than one REG_REQUEST parameter in its I2 or UPDATE packets, while the registrar MUST be able to process one or more REG_REQUEST parameters in received I2 or UPDATE packets. Bestie, that's a whole power-balance situation ๐Ÿ’…

When the registrar receives a registration with a lifetime that is either smaller or greater than the minimum or maximum lifetime, respectively, then it SHOULD grant the registration for the minimum or maximum lifetime, respectively. So if the ask is too short or too long, the registrar SHOULD clamp it to the closest edge ๐Ÿซถ

And lastly, HIP_SIGNATURE protects the parameter within the I2 and UPDATE packets. Lowkey the security glow-up ๐Ÿ”


4.4. REG_RESPONSE ๐ŸŽ€

This is the registrar's answer to REG_REQUEST, sent back in R2 or UPDATE packets. It's giving "here's what you actually got" ๐Ÿฆ‹

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             Type              |             Length            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Lifetime    |  Reg Type #1  |  Reg Type #2  |  Reg Type #3  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      ...      |     ...       |  Reg Type #n  |               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    Padding    +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   Type        934
   Length      Length in octets, excluding Type, Length, and Padding.
   Lifetime    Granted registration lifetime.
   Reg Type    The granted registration types in order of preference.

Other documents will define specific values for registration types. See Section 7 for more information.

Here's the tea โ˜• The registrar SHOULD include a REG_RESPONSE parameter in its R2 or UPDATE packet only if a registration has successfully completed. The registrar MUST NOT include more than one REG_RESPONSE parameter in its R2 or UPDATE packets, while the requester MUST be able to process one or more REG_RESPONSE parameters in received R2 or UPDATE packets.

The requester MUST be prepared to receive any registration lifetime, including ones beyond the minimum and maximum lifetime indicated in the REG_INFO parameter. It MUST NOT expect that the returned lifetime will be the requested one, even when the requested lifetime falls within the announced minimum and maximum. So don't get attached to the lifetime you asked for, babe, the registrar gets the final say ๐Ÿ™ˆ

Once again, HIP_SIGNATURE protects the parameter within the R2 and UPDATE packets. Iconic ๐Ÿ‘‘


4.5. REG_FAILED ๐Ÿ’€

This one's the "sorry bestie, not yet" parameter ๐Ÿ˜ญ

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             Type              |             Length            |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Failure Type  |  Reg Type #1  |  Reg Type #2  |  Reg Type #3  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |      ...      |     ...       |  Reg Type #n  |               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    Padding    +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    Type          936
    Length        Length in octets, excluding Type, Length, and Padding.
    Failure Type  Reason for failure.
    Reg Type      The registration types that failed with the specified
                  reason.
    Failure Type    Reason
    ------------    --------------------------------------------
    0               Registration requires additional credentials
    1               Registration type unavailable
    2-200           Unassigned
    201-255         Reserved by IANA for private use

Other documents will define specific values for registration types. See Section 7 for more information.

A failure type of zero means a registrar requires additional credentials to authorize a requester to register with the registration types listed in the parameter. A failure type of one means that the requested service type is unavailable at the registrar. Failure types other than zero (0) and one (1) have not been defined. So right now only 0 and 1 are real, everything else is still a mystery ๐Ÿ”ฎ

The registrar SHOULD include the REG_FAILED parameter in its R2 or UPDATE packet, if registration with the registration types listed has not completed successfully and a requester is asked to try again with additional credentials. In other words, when the registrar says "try again with more credentials," the REG_FAILED parameter is the one doing the talking ๐Ÿ—ฃ๏ธ

HIP_SIGNATURE protects the parameter within the R2 and UPDATE packets. Same energy as always ๐Ÿ”


5. Establishing and Maintaining Registrations ๐ŸŒธ

Okay, so setting up and keeping up a registration might need extra info that just isn't in the REG_REQUEST or REG_RESPONSE parameters. That's why registration type definitions MAY define dependencies for HIP parameters that are not defined in this document. Their semantics are subject to the specific registration type specifications. Basically, the details live in the type's own spec, not here ๐Ÿ“š

The minimum lifetime both registrars and requesters MUST support is 10 seconds, while they SHOULD support a maximum lifetime of 120 seconds, at least. These values are the baseline for the services built on the registration system. They were picked to be neither too short nor too long, and to accommodate existing timeouts of state established in middleboxes (e.g., NATs and firewalls.) Little bit of middlebox drama in there ๐Ÿ“

A zero lifetime is reserved for canceling purposes. Requesting a zero lifetime for a registration type is equal to canceling the registration of that type. A requester MAY cancel a registration before it expires by sending a REG_REQ to the registrar with a zero lifetime. A registrar SHOULD respond and grant a registration with a zero lifetime. A registrar (and an attached service) MAY cancel a registration before it expires, at its own discretion. However, if it does so, it SHOULD send a REG_RESPONSE with a zero lifetime to all registered requesters. So zero means "bye," and the registrar can also ghost you early if it needs to, but it's supposed to tell everyone who's registered ๐Ÿ‘‹๐Ÿฆ‹


6. Security Considerations ๐Ÿ’œ

โš ๏ธ Heads up, this part is serious, so let's be extra careful here! โš ๏ธ

This section discusses the threats on the HIP registration protocol, and their implications on the overall security of HIP. In particular, it argues that the extensions described in this document do not introduce additional threats to HIP.

The extensions described in this document rely on the HIP base exchange and do not modify its security characteristics, e.g., digital signatures or HMAC. Hence, the only threat introduced by these extensions is related to the creation of soft registration state at the registrar.

Registrars act on a voluntary basis and are willing to accept being a responder and then to create HIP associations with a number of previously unknown hosts. Because they have to store HIP association state anyway, adding a certain amount of time-limited HIP registration state should not introduce any serious additional threats, especially because HIP registrars may cancel registrations at any time at their own discretion, e.g., because of resource constraints during an attack.

7. IANA Considerations ๐Ÿฆ‹

This section is to be interpreted according to the Guidelines for Writing an IANA Considerations Section in RFCs [RFC2434].

This document updates the IANA Registry for HIP Parameter Types by assigning new HIP Parameter Types values for the new HIP Parameters defined in this document:

  • REG_INFO (defined in Section 4.2)
  • REG_REQUEST (defined in Section 4.3)
  • REG_RESPONSE (defined in Section 4.4)
  • REG_FAILED (defined in Section 4.5)

IANA has allocated the Notify Message Type code 51 for the REG_REQUIRED notification error type in the Notify Message Type registry.

IANA has opened a new registry for registration types. This document does not define registration types but makes the following reservations:

   Reg Type        Service
   --------        -------
   0-200           Unassigned
   201-255         Reserved by IANA for private use

Adding a new type requires new IETF specifications.

IANA has opened a new registry for registration failure types. This document makes the following failure type definitions and reservations:

   Failure Type    Reason
   ------------    --------------------------------------------
   0               Registration requires additional credentials
   1               Registration type unavailable
   2-200           Unassigned
   201-255         Reserved by IANA for private use

Adding a new type requires new IETF specifications.


8. Acknowledgments ๐Ÿซถ

The following people (in alphabetical order) have provided thoughtful and helpful discussions and/or suggestions that have helped to improve this document: Jeffrey Ahrenholz, Miriam Esteban, Mika Kousa, Pekka Nikander, and Hannes Tschofenig. Thank you, legends ๐ŸŒˆ


9. References ๐Ÿ“–

9.1. Normative References

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.

[RFC5201] Moskowitz, R., Nikander, P., Jokela, P., Ed., and T. Henderson, "Host Identity Protocol", RFC 5201, April 2008.

9.2. Informative References

[RFC3234] Carpenter, B. and S. Brim, "Middleboxes: Taxonomy and Issues", RFC 3234, February 2002.

[RFC4423] Moskowitz, R. and P. Nikander, "Host Identity Protocol (HIP) Architecture", RFC 4423, May 2006.

[RFC5204] Laganier, J. and L. Eggert, "Host Identity Protocol (HIP) Rendezvous Extension", RFC 5204, April 2008.


Authors' Addresses ๐Ÿ’Œ

Julien Laganier DoCoMo Communications Laboratories Europe GmbH Landsberger Strasse 312 Munich 80687 Germany

Phone: +49 89 56824 231 EMail: julien.ietf@laposte.net URI: http://www.docomolab-euro.com/

Teemu Koponen Helsinki Institute for Information Technology Advanced Research Unit (ARU) P.O. Box 9800 Helsinki FIN-02015-HUT Finland

Phone: +358 9 45 1 EMail: teemu.koponen@iki.fi URI: http://www.hiit.fi/

Lars Eggert Nokia Research Center P.O. Box 407 Nokia Group 00045 Finland

Phone: +358 50 48 24461 EMail: lars.eggert@nokia.com URI: http://research.nokia.com/people/lars_eggert/

Okay, legal bit, but make it cute ๐ŸŽ€. The copyright is held by The IETF Trust (2008) ๐Ÿ’…. This document is covered by the rights, licenses and restrictions in BCP 78, and apart from what BCP 78 says, the authors keep all their own rights ๐Ÿซถ.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐Ÿ’€

Intellectual Property ๐Ÿฆ‹

Okay, so the IETF takes no position on whether any Intellectual Property Rights (or other rights someone might claim) cover the tech in this document are valid or how far they reach ๐Ÿง. It also doesn't say whether any license for those rights is available, and it hasn't independently gone looking for any such rights either ๐Ÿ™ˆ. If you want the rules on rights in RFC documents, check out BCP 78 and BCP 79 ๐Ÿ“š.

Any IPR disclosures sent to the IETF Secretariat, plus any assurances that licenses will be made available, are the place to look ๐Ÿ’œ. The same goes for results of an attempt to get a general license or permission to use those proprietary rights, for implementers or users of this spec. You can find all of that in the IETF's online IPR repository at http://www.ietf.org/ipr โœจ.

And the IETF genuinely wants to hear from you ๐Ÿซถ. If you know about any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard, please tell the IETF at ietf-ipr@ietf.org ๐ŸŒธ. Bestie, that's the whole thing ๐ŸŽ€ periodt.

๐Ÿ“ฆ where this page comes from