RFC 6316

Sockets Application Program Interface (API) for Multihoming Shim

๐Ÿ“… published July 2011, from ietf

Sockets Application Program Interface (API) for Multihoming Shim ๐Ÿฆ‹

Okay bestie, this is RFC 6316 ๐Ÿ’– It came out in July 2011 and it's Informational, so it's here to inform, not a Standards Track spec ๐Ÿงš The ISSN is 2070-1721. The authors are M. Komu (Aalto University), M. Bagnulo (UC3M), K. Slavov (Ericsson), and S. Sugimoto, Ed. (Ericsson). The "Ed." just means they were the editor ๐Ÿ’… The header doesn't list any RFCs this one obsoletes or updates, so it doesn't replace or change anything else ๐ŸŒˆ

Abstract ๐ŸŒธ

So this doc specifies sockets API extensions for the multihoming shim layer. The big goal is letting applications and the shim layer talk to each other for advanced locator management, and getting info about failure detection and path exploration ๐Ÿซถ

It's built on one assumption: a multihomed host has a conceptual sub-layer (we're calling it the "shim sub-layer") inside the IP layer that keeps track of mappings between identifiers and locators. Shim6 and the Host Identity Protocol (HIP) are examples of the shim โœจ


Status of This Memo ๐Ÿ“

This document is not an Internet Standards Track specification. It's published for informational purposes ๐Ÿงš

It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). Not every IESG-approved doc is a candidate for any level of Internet Standard, so see Section 2 of RFC 5741 if you want the details ๐Ÿค“

For the current status, any errata, and how to give feedback, check out http://www.rfc-editor.org/info/rfc6316 ๐Ÿ”—

Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they're in effect on the publication date. Please actually read these, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes ๐Ÿ“œ

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. Some of the people who hold copyright in that older material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you get a proper license from those copyright holders, this document can't be modified outside the IETF Standards Process, and you can't create derivative works of it outside that process. The exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐ŸŒธ

Table of Contents ๐Ÿ—‚๏ธ

   1. Introduction ....................................................3
   2. Requirements Language ...........................................4
   3. Terminology and Background ......................................4
   4. System Overview .................................................7
   5. Requirements ....................................................8
   6. Socket Options for Multihoming Shim Sub-Layer ..................10
      6.1. SHIM_ASSOCIATED ...........................................14
      6.2. SHIM_DONTSHIM .............................................15
      6.3. SHIM_HOT_STANDBY ..........................................16
      6.4. SHIM_LOC_LOCAL_PREF .......................................17
      6.5. SHIM_LOC_PEER_PREF ........................................18
      6.6. SHIM_LOC_LOCAL_RECV .......................................19
      6.7. SHIM_LOC_PEER_RECV ........................................20
      6.8. SHIM_LOC_LOCAL_SEND .......................................20
      6.9. SHIM_LOC_PEER_SEND ........................................22
      6.10. SHIM_LOCLIST_LOCAL .......................................23
      6.11. SHIM_LOCLIST_PEER ........................................25
      6.12. SHIM_APP_TIMEOUT .........................................26
      6.13. SHIM_PATHEXPLORE .........................................27
      6.14. SHIM_DEFERRED_CONTEXT_SETUP ..............................28
      6.15. Applicability ............................................28
      6.16. Error Handling ...........................................29
   7. Ancillary Data for Multihoming Shim Sub-Layer ..................29
      7.1. Get Locator from Incoming Packet ..........................30
      7.2. Set Locator for Outgoing Packet ...........................30
      7.3. Notification from Application to Multihoming Shim
           Sub-Layer .................................................31
      7.4. Applicability .............................................31
   8. Data Structures ................................................32
      8.1. Data Structure for Locator Information ....................32
           8.1.1. Handling Locator behind NAT ........................33
      8.2. Path Exploration Parameter ................................34
      8.3. Feedback Information ......................................35
   9. System Requirements ............................................36
   10. Relation to Existing Sockets API Extensions ...................36
   11. Operational Considerations ....................................37
      11.1. Conflict Resolution ......................................37
      11.2. Incompatibility between IPv4 and IPv6 ....................38
   12. IANA Considerations ...........................................38
   13. Protocol Constant .............................................38
   14. Security Considerations .......................................38
      14.1. Treatment of Unknown Locator .............................39
           14.1.1. Treatment of Unknown Source Locator ...............39
           14.1.2. Treatment of Unknown Destination Locator ..........39
   15. Acknowledgments ...............................................40
   16. References ....................................................40
      16.1. Normative References .....................................40
      16.2. Informative References ...................................41
   Appendix A. Context Forking .......................................42

1. Introduction โœจ

Okay so this doc defines sockets API extensions that let upper-layer protocols find out about, and control, how the multihoming shim sub-layer in the IP layer handles its dynamic choice of locators ๐Ÿฆ‹ Right now the shim sub-layer is basically Shim6 and/or HIP, but it's defined generically, so it's not locked to just those two ๐Ÿ’…

The shim sub-layer (we'll call it "shim sub-layer" in this doc) has one main job: keeping upper-layer protocols unbothered when the endhost changes its attachment point to the Internet. A rehoming event in a multihomed setup is a classic example ๐ŸŒˆ But there are two situations where an API is really needed: 1) when the upper-layer protocol is super sensitive to these changes, or 2) when the upper-layer protocol wants to level up by knowing more about what's happening underneath ๐Ÿ‘‘

There are a bunch of different technologies trying to solve the same multihoming issue, and they can conflict if more than one shim sub-layer is active on the same time ๐Ÿ˜ญ So this doc assumes there's only a single shim sub-layer (HIP or Shim6) activated on the system ๐Ÿ”ฅ

The target readers are application programmers who build software that can really benefit from multihomed environments. This doc also gives shim protocol developers the info they need to implement APIs for advanced locator management ๐Ÿซถ

2. Requirements Language ๐ŸŽ€

Quick vibe check on 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 [RFC2119] ๐Ÿ’…

3. Terminology and Background ๐Ÿ“š

okay so this section is the vocab list, bestie ๐Ÿซถ most of the terms in this doc are borrowed from three other docs:

  • Shim6 Protocol Specification [RFC5533]
  • HIP Architecture [RFC4423]
  • Reachability Protocol (REAP) [RFC5534]

quick heads up: in this doc, "IP" means both IPv4 and IPv6 unless it says a specific version ๐Ÿ’… here are the terms that come up a lot:

  • Endpoint Identifier (EID) -- the identifier the application uses to say which endpoint a communication is for ๐Ÿฆ‹ apps can handle EIDs in different ways, like long-lived connections, callbacks, and referrals [SHIM6-APP-REFER].
    • in Shim6, the EID is a ULID (Upper-Layer Identifier) ๐ŸŒธ a ULID gets picked from the locators that exist on the host.
    • in HIP, the EID is a Host Identifier ๐Ÿ”‘ it's derived from a host's public key. for backward compatibility with the sockets API, it's shown as a hash of that public key.
    • the EID shows up in the standard sockets API as an address, but NOT in the extensions this doc defines, which only care about locators. ๐Ÿ™ˆ
  • Locator -- the IP address that's actually used to deliver IP packets ๐Ÿ“ฎ locators sit in the source and destination fields of the IP header on the wire. in this doc, a locator can be an IPv4 address or an IPv6 address. the tea: HIP can do both IPv4 and IPv6 locators, but Shim6 can only do IPv6 locators ๐Ÿต with HIP, a locator can be a private IPv4 address if the host is behind a NAT. Section 8.1.1 has the full details on that one ๐Ÿ‘‘
    • List of locators -- a list of locators tied to an EID โœจ a given context stores two of these, one for the local EID and one for the remote EID. as [RFC5533] defines, the list for an EID 'A' is written Ls(A).
    • Preferred locator -- the source or destination locator being used right now to send packets in a given context ๐Ÿ’–
    • Unknown locator -- any locator that isn't in the locator list of the shim context tied to the socket. if there's no shim context on the socket, then any source or destination locator the app asks for counts as unknown ๐Ÿ‘€
    • Valid locator -- a locator that's valid in the security sense ๐Ÿ” it's about whether the locator is part of a Hash-Based Address (HBA) set [RFC5535].
    • Verified locator -- a locator that's been confirmed as reachable by a REAP return routability check ๐Ÿงš the verification only applies to the peer's locator, not yours.
  • Shim -- the conceptual sub-layer inside the IP layer ๐Ÿง it keeps track of the mappings between EIDs and locators. an EID can have more than one locator at a time when the host is multihomed. "shim" isn't a specific protocol, just a name for that sub-layer inside IP ๐Ÿ’œ
  • Identifier/locator adaptation -- the adaptation the shim sub-layer does ๐Ÿ”„ it might rewrite the source and/or destination addresses of an IP packet. on the way out, the EID pair gets converted to the matching locator pair. on the way in, the locator pair gets converted back to the EID pair.
  • Context -- the state info shared by a pair of peers ๐ŸŽ€ a context stores the binding between the EID and its locators, and the shim sub-layer maintains it. deferred context setup is when a context gets set up after the communication has already started ๐ŸŒˆ that's only possible if the ULID is routable, like in Shim6.
  • Reachability detection -- the procedure for checking reachability between a given locator pair ๐Ÿ”
  • Path -- the sequence of routers an IP packet goes through to reach its destination ๐Ÿ›ฃ๏ธ
  • Path exploration -- the procedure for exploring the available paths for a given set of locator pairs ๐Ÿ—บ๏ธ
  • Outage -- the incident that stops IP packets from flowing from the source locator to the destination locator ๐Ÿ’€ during an outage, there's no reachability between that locator pair. outages can happen for lots of reasons, like not enough network resources, congestion, or human error (faulty operation) ๐Ÿ™ƒ
  • Working address pair -- counts as "working" if the packet can safely travel from source to destination ๐Ÿฆ„ the packet has the first address of the pair as its source and the second as its destination. if reachability is confirmed in both directions, the pair is working bi-directionally โœ…
  • Reachability Protocol (REAP) -- the protocol for detecting failure and exploring reachability in a multihomed environment ๐Ÿ’… REAP is defined in [RFC5534].

okay so in this doc, the syntax and semantics of the API are written the same way as the Portable Operating System Interface (POSIX) standard [POSIX] ๐Ÿงพ the API says how to use ancillary data (aka cmsg) to get at the locator info with the recvmsg() and/or sendmsg() I/O calls. the API is described in C, with POSIX-style data types: intN_t means a signed integer of exactly N bits (like int16_t), and uintN_t means an unsigned integer of exactly N bits (like uint32_t) ๐Ÿค“

the difference between "connected" and "unconnected" sockets matters a LOT for where this sockets API applies ๐Ÿซฃ a connected socket is bound to one specific peer, but an unconnected socket isn't bound to any specific peers. a TCP socket becomes connected once the TCP connection establishment is done ๐Ÿค UDP sockets are unconnected, unless the app uses the connect() system call ๐Ÿ“ก


4. System Overview ๐ŸŒธ

so Figure 1 is the big picture โœจ the shim sub-layer and the REAP component both live inside the IP layer. apps use the sockets API defined here to talk to the shim sub-layer and the transport layer for locator management, failure detection, and path exploration ๐Ÿ’–

it's also possible for the shim sub-layer to interact with the transport layer, but that interaction is outside the scope of this document ๐Ÿ™…โ€โ™€๏ธ

                        +------------------------+
                        |       Application      |
                        +------------------------+
                           ^                 ^
              ~~~~~~~~~~~~~|~Socket Interface|~~~~~~~~~~~~~~
                           |                 v
               +-----------|------------------------------+
               |           |  Transport Layer             |
               +-----------|------------------------------+
                     ^     |
       +-------------|-----|-------------------------------------+
       |             v     v                                     |
       |   +-----------------------------+       +----------+    |  IP
       |   |            Shim             |<----->|   REAP   |    | Layer
       |   +-----------------------------+       +----------+    |
       |                       ^                      ^          |
       +-----------------------|----------------------|----------+
                               v                      v
               +------------------------------------------+
               |                Link Layer                |
               +------------------------------------------+

                         Figure 1: System Overview

5. Requirements ๐Ÿ’…

okay so bestie, this section is basically the wishlist ๐Ÿ“โœจ the applications are telling the shim sub-layer exactly what they need from it, and honestly it's giving very organized main character energy ๐Ÿ‘‘

5.1. Turn on/off shim ๐ŸŽ€

hmm wait, first things first: an application should be able to decide whether the multihoming support gets switched on or off by the shim layer ๐Ÿฆ‹

  • Apply shim ๐ŸŒธ: the application should be able to explicitly request that the shim sub-layer apply multihoming support.
  • Don't apply shim ๐Ÿ™ˆ: the application should be able to request that the shim sub-layer not apply the multihoming support but apply normal IP processing at the IP layer.
  • Note that this function is also required by other types of multihoming mechanisms, such as the Stream Control Transmission Protocol (SCTP) and multipath TCP, to avoid potential conflict with the shim sub-layer. ngl this is a very important detail, so don't skip it ๐Ÿ’œ

5.2. Locator management ๐Ÿงš

okay this one is all about being in control of your locators ๐Ÿ’–

  • It should be possible to set a preferred source and/or destination locator within a given context.
  • It should be possible to get a preferred source and/or destination locator within a given context.
  • It should be possible to set a list of source and/or destination locators within a given context: Ls(local) and Ls(remote).
  • It should be possible to get a list of source and/or destination locators within a given context: Ls(local) and Ls(remote).

5.3. Notification from applications and upper-layer protocols to the shim sub-layer ๐Ÿ“ฃ

this is the part where the app basically tells the shim how things are going ๐Ÿซถ it happens in an event-based manner, and applications and/or upper-layer protocols may provide positive feedback or negative feedback to the shim sub-layer. these types of feedback are mentioned in [RFC5534]:

  • Applications and/or upper-layer protocols (e.g., TCP) may provide positive feedback to the shim sub-layer informing that the communication is going well. โœจ good vibes only
  • Applications and/or upper-layer protocols (e.g., TCP) may provide negative feedback to the shim sub-layer informing that the communication status is not satisfactory. TCP may detect a problem when it does not receive any expected ACK message from the peer. The REAP module may be triggered by the negative feedback and invoke the path exploration procedure. ๐Ÿ˜ญ this is the drama moment, the REAP module literally gets triggered and goes looking for new paths

5.4. Feedback from applications to the shim sub-layer ๐Ÿ’ฌ

applications should be able to inform the shim sub-layer of the timeout values for detecting failures, sending keepalives, and starting the exploration procedure. and in particular, applications should be able to suppress keepalives ๐Ÿ™ˆ the ability to say "no keepalives pls" is iconic, periodt ๐Ÿ’…

5.5. Hot-standby ๐Ÿ”ฅ

applications may request the shim sub-layer for a hot-standby capability. this means alternative paths are known to be working in advance of a failure detection, so if something breaks, it is possible for the shim sub-layer to immediately replace the current locator pair with an alternative locator pair. no waiting around, just swap ๐ŸŒˆ

5.6. Eagerness for locator exploration ๐Ÿฆ‹

an application should be able to tell the shim sub-layer how aggressively it wants the REAP mechanism to perform a path exploration, for example by specifying the number of concurrent attempts of discovery of working locator pairs, when an outage occurs on the path between the locator pair in use. the more eager, the more hype ๐Ÿ“

5.7. Providing locator information to applications ๐Ÿงšโ€โ™€๏ธ

an application should be able to obtain information about the locator pair that was actually used to send or receive packets. this is lowkey so useful because it means the app can check whether its locator preference actually got applied to the flow ๐Ÿ‘€

  • For inbound traffic, the application may be interested in the locator pair that was actually used to receive the packet.
  • For outbound traffic, the application may be interested in the locator pair that was actually used to transmit the packet.

in this way, applications may have additional control of the locator management. for example, an application becomes capable of verifying if its preference for a locator is actually applied to the flow or not. main character energy, fr fr ๐ŸŒˆ

5.8. Deferred context setup ๐ŸŽ€

applications should be able to know if the shim sub-layer supports deferred context setup or not. โœจ

5.9. Shim status ๐ŸŒธ

an application should be able to know if the communication is now being served by the shim sub-layer or not. ๐Ÿซถ

5.10. Common interface for locators ๐Ÿ’œ

an application should be able to use a common interface to access an IPv4 locator and an IPv6 locator. no more juggling two different APIs, bestie ๐Ÿ‘‘

6. Socket Options for Multihoming Shim Sub-Layer โœจ

okay bestie, this section is where we get into the actual socket options the shim sub-layer gives you ๐ŸŽ€ these are all defined at the level SOL_SHIM, so whenever an app calls getsockopt() or setsockopt() with one of them, the second argument MUST be SOL_SHIM ๐Ÿ’… no cap, that part is non-negotiable.

Table 1 is the full lineup of shim-specific options. The second column tells you if you can read the value with getsockopt(), the third tells you if you can write it with setsockopt(), the fourth gives you a quick vibe check on what it does, and the fifth shows the data type that comes along with it. Unless it says otherwise, the data type is an integer ๐ŸŒธ

   +-----------------------------+-----+-----+-----------------+-------+
   | optname                     | get | set | description     | dtype |
   +-----------------------------+-----+-----+-----------------+-------+
   | SHIM_ASSOCIATED             | o   |     | Get the         | int   |
   |                             |     |     | parameter that  |       |
   |                             |     |     | indicates       |       |
   |                             |     |     | whether the     |       |
   |                             |     |     | socket is       |       |
   |                             |     |     | associated (1)  |       |
   |                             |     |     | with any shim   |       |
   |                             |     |     | context or not  |       |
   |                             |     |     | (0).            |       |
   | SHIM_DONTSHIM               | o   | o   | Get or set the  | int   |
   |                             |     |     | parameter that  |       |
   |                             |     |     | indicates       |       |
   |                             |     |     | whether or not  |       |
   |                             |     |     | to employ       |       |
   |                             |     |     | multihoming     |       |
   |                             |     |     | support by the  |       |
   |                             |     |     | shim sub-layer. |       |
   | SHIM_HOT_STANDBY            | o   | o   | Get or set the  | int   |
   |                             |     |     | parameter to    |       |
   |                             |     |     | request the     |       |
   |                             |     |     | shim sub-layer  |       |
   |                             |     |     | to prepare a    |       |
   |                             |     |     | hot-standby     |       |
   |                             |     |     | connection.     |       |
   | SHIM_LOC_LOCAL_PREF         | o   | o   | Set the         | Note  |
   |                             |     |     | preference      | 1     |
   |                             |     |     | value for a     |       |
   |                             |     |     | source locator  |       |
   |                             |     |     | for outbound    |       |
   |                             |     |     | traffic.  Get   |       |
   |                             |     |     | the preferred   |       |
   |                             |     |     | locator for the |       |
   |                             |     |     | source locator  |       |
   |                             |     |     | for outbound    |       |
   |                             |     |     | traffic.        |       |
   | SHIM_LOC_PEER_PREF          | o   | o   | Set the         | Note  |
   |                             |     |     | preference      | 1     |
   |                             |     |     | value for a     |       |
   |                             |     |     | destination     |       |
   |                             |     |     | locator for     |       |
   |                             |     |     | outbound        |       |
   |                             |     |     | traffic.  Get   |       |
   |                             |     |     | the preferred   |       |
   |                             |     |     | locator for the |       |
   |                             |     |     | destination     |       |
   |                             |     |     | locator for     |       |
   |                             |     |     | outbound        |       |
   |                             |     |     | traffic.        |       |
   | SHIM_LOC_LOCAL_RECV         | o   | o   | Request the     | int   |
   |                             |     |     | shim sub-layer  |       |
   |                             |     |     | to store the    |       |
   |                             |     |     | destination     |       |
   |                             |     |     | locator of the  |       |
   |                             |     |     | received IP     |       |
   |                             |     |     | packet in an    |       |
   |                             |     |     | ancillary data  |       |
   |                             |     |     | object.         |       |
   | SHIM_LOC_PEER_RECV          | o   | o   | Request the     | int   |
   |                             |     |     | shim sub-layer  |       |
   |                             |     |     | to store the    |       |
   |                             |     |     | source locator  |       |
   |                             |     |     | of the received |       |
   |                             |     |     | IP packet in an |       |
   |                             |     |     | ancillary data  |       |
   |                             |     |     | object.         |       |
   | SHIM_LOC_LOCAL_SEND         | o   | o   | Get or set the  | Note  |
   |                             |     |     | source locator  | 1     |
   |                             |     |     | of outgoing IP  |       |
   |                             |     |     | packets.        |       |
   | SHIM_LOC_PEER_SEND          | o   | o   | Get or set the  | Note  |
   |                             |     |     | destination     | 1     |
   |                             |     |     | locator of      |       |
   |                             |     |     | outgoing IP     |       |
   |                             |     |     | packets.        |       |
   | SHIM_LOCLIST_LOCAL          | o   | o   | Get or set the  | Note  |
   |                             |     |     | list of         | 2     |
   |                             |     |     | locators        |       |
   |                             |     |     | associated with |       |
   |                             |     |     | the local EID.  |       |
   | SHIM_LOCLIST_PEER           | o   | o   | Get or set the  | Note  |
   |                             |     |     | list of         | 2     |
   |                             |     |     | locators        |       |
   |                             |     |     | associated with |       |
   |                             |     |     | the peer's EID. |       |
   | SHIM_APP_TIMEOUT            | o   | o   | Get or set the  | int   |
   |                             |     |     | Send Timeout    |       |
   |                             |     |     | value of REAP.  |       |
   | SHIM_PATHEXPLORE            | o   | o   | Get or set      | Note  |
   |                             |     |     | parameters for  | 3     |
   |                             |     |     | path            |       |
   |                             |     |     | exploration and |       |
   |                             |     |     | failure         |       |
   |                             |     |     | detection.      |       |
   | SHIM_CONTEXT_DEFERRED_SETUP | o   |     | Get the         | int   |
   |                             |     |     | parameter that  |       |
   |                             |     |     | indicates       |       |
   |                             |     |     | whether         |       |
   |                             |     |     | deferred        |       |
   |                             |     |     | context setup   |       |
   |                             |     |     | is supported or |       |
   |                             |     |     | not.            |       |
   +-----------------------------+-----+-----+-----------------+-------+

          Table 1: Socket Options for Multihoming Shim Sub-Layer

Quick decoder ring for the table notes ๐Ÿ”

   Note 1: Pointer to a shim_locator as defined in Section 8.

   Note 2: Pointer to an array of shim_locator data.

   Note 3: Pointer to a shim_pathexplore as defined in Section 8.

Figure 2 shows where all this lives in the sockets API system model ๐Ÿฆ‹ The shim sub-layer, plus the IPv4 and IPv6 bits sitting underneath it, are the new kids on the block. And yep, like we said, every shim-specific option is at SOL_SHIM level. Why? Three big wins:

  1. The existing sockets APIs keep working at the layer above the shim sub-layer. Those legacy APIs still treat IP addresses as identifiers, so nothing breaks for them ๐Ÿฅน
  2. With the newly defined shim socket options, the app gets extra control over locator management ๐Ÿ‘‘
  3. The shim-specific options can stay independent from the address family (IPPROTO_IP or IPPROTO_IPV6) and the transport protocol (IPPROTO_TCP or IPPROTO_UDP) settings โœจ
                            s1 s2      s3 s4
                             |  |       |  |
            +----------------|--|-------|--|----------------+
            |             +-------+   +-------+             |
            | IPPROTO_TCP |  TCP  |   |  UDP  |             |
            |             +-------+   +-------+             |
            |                |   \     /   |                |
            |                |    -----    |                |
            |                |   /     \   |                |
            |              +------+   +------+              |
            |   IPPROTO_IP | IPv4 |   | IPv6 | IPPROTO_IPV6 |
            |              +------+   +------+              |
            |                  \         /             SOL_SOCKET
            |          +--------\-------/--------+          |
            | SOL_SHIM |          shim           |          |
            |          +--------/-------\--------+          |
            |                  /         \                  |
            |              +------+   +------+              |
            |              | IPv4 |   | IPv6 |              |
            |              +------+   +------+              |
            |                  |          |                 |
            +------------------|----------|-----------------+
                               |          |
                             IPv4       IPv6
                           Datagram   Datagram

         Figure 2: System Model of Sockets API with Shim Sub-Layer

That's the whole socket options section, babe! ๐ŸŒˆ๐Ÿ’–

6.1. SHIM_ASSOCIATED โœจ

okay so SHIM_ASSOCIATED ๐Ÿฆ‹ is the option that lets you check whether your socket is hooked up to a shim context at all. ngl it's super useful when the locator info on an incoming IP packet doesn't tell you whether identifier/locator adaptation happened. ๐Ÿซถ And heads up, the EID pair and the locator pair can literally be identical in some cases, so don't assume they're always different!

It's read-only, so you read it with getsockopt(), and the result (0/1/2) lands in the option value, which is the fourth argument of getsockopt(). ๐Ÿ’…

If you try to use it on an unconnected socket, you get EOPNOTSUPP back. ๐Ÿ’€

The data type is an integer. A return value of 1 means the socket has a shim context at the shim sub-layer. A return value of 0 means there's no shim context on the socket. A return value of 2 means it's unknown whether the socket has a shim context, and this MUST be returned only when the socket is unconnected. So once the socket is connected, the returned value MUST be 0 or 1. Periodt ๐Ÿ‘‘

Here's how an app can use it:

    int optval;
    int optlen = sizeof(optval);

    getsockopt(fd, SOL_SHIM, SHIM_ASSOCIATED, &optval, &optlen);

6.2. SHIM_DONTSHIM ๐ŸŒธ

SHIM_DONTSHIM is the option for when you want the shim layer to NOT give multihoming support to the communication on your socket. Like, you're basically saying "no thanks, bestie" ๐Ÿ™ˆ

The data type is an integer, and it's either 0 or 1. A value of 0 means the shim sub-layer is used if it's available. A value of 1 means the app doesn't want the shim sub-layer doing multihoming support for that socket. ๐Ÿงš

The default is 0, which means the shim sub-layer does identifier/locator adaptation if it's available. โœจ

Any attempt to turn off the multihoming shim support MUST be made by the app before the socket is connected. If an app tries this on a connected socket, EOPNOTSUPP MUST be returned. Don't wait till after you connect, bestie! ๐Ÿ˜ญ

An app can ask the system to skip the multihoming support like this:

    int optval;

    optval = 1;

    setsockopt(fd, SOL_SHIM, SHIM_DONTSHIM, &optval, sizeof(optval));

And the app can check the value like this:

    int optval;
    int len;

    len = sizeof(optval);

    getsockopt(fd, SOL_SHIM, SHIM_DONTSHIM, &optval, &len);

6.3. SHIM_HOT_STANDBY ๐Ÿ“

SHIM_HOT_STANDBY controls whether the shim sub-layer uses a hot-standby connection for the socket. A hot-standby connection is an alternative working locator pair to the current locator pair, so it's like a backup dancer ready to step in ๐Ÿ’ƒ This option only does anything when there's a shim context on the socket. ๐ŸŽ€

The data type is an integer. You can set it with setsockopt() and read it with getsockopt(). ๐Ÿ’–

By default it's 0, which means hot-standby is disabled. ๐Ÿ™…

If you use it on an unconnected socket, you get EOPNOTSUPP. If there's no shim context on the socket, you get ENOENT instead. ๐Ÿ’€

To turn on a hot-standby connection, an app does this:

    int optval;

    optval = 1;

    setsockopt(fd, SOL_SHIM, SHIM_HOT_STANDBY, &optval,
               sizeof(optval));

To get the current value, an app does this:

    int optval;
    int len;

    len = sizeof(optval);

    getsockopt(fd, SOL_SHIM, SHIM_HOT_STANDBY, &optval, &len);

6.4. SHIM_LOC_LOCAL_PREF ๐Ÿ’œ

SHIM_LOC_LOCAL_PREF is used to set the preference value for a source locator for outbound traffic. You can also use it to get the preference value of the source locator for outbound traffic that has the highest preference value. It's giving "pick your favourite outfit" energy ๐Ÿ‘—โœจ

This option only works when there's a shim context on the socket. โœจ

By default the option value is NULL, which means the option is disabled. ๐Ÿซ 

A locator's preference is a combo of priority and weight, as per DNS SRV [RFC2782]. Fun fact, the Shim6 base protocol defines locator preference in the same way too! ๐ŸŒˆ

The data type is a pointer to the shim_locator information data structure, which is defined in Section 8.1. ๐Ÿงš

If an app uses this on an unconnected socket, you get EOPNOTSUPP. If there's no shim context on the socket, you get ENOENT. ๐Ÿ’€

If the validation of the specified locator fails, you get EINVALIDLOCATOR. ๐Ÿ˜ญ

To set the preference for a source locator for outbound traffic, the app uses setsockopt() with this option. Heads up, lc_ifidx and lc_flags (as defined in Section 8.1) do nothing in a set operation, so don't stress about them. ๐Ÿ™ˆ Here's an example set operation:

    struct shim_locator lc;
    struct in6_addr ip6;

    /* ...set the locator (ip6)... */

    memset(&lc, 0, sizeof(shim_locator));
    lc.lc_family = AF_INET6;  /* IPv6 */
    lc.lc_ifidx = 0;
    lc.lc_flags = 0;
    lc.lc_prio = 1;
    lc.lc_weight = 10;
    memcpy(&lc.lc_addr, &ip6, sizeof(in6_addr));

    setsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_PREF, &lc,
               sizeof(optval));

To get the source locator for outbound traffic with the highest preference value, the app uses the option like this:

    struct shim_locator lc;
    int len;

    len = sizeof(lc);

    getsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_PREF, &lc, &len);

6.5. SHIM_LOC_PEER_PREF ๐Ÿฆฉ

SHIM_LOC_PEER_PREF is the same vibe as the last one, but for the destination side. You use it to set the preference value for a destination locator for outbound traffic, or to get the preference value of the destination locator for outbound traffic that has the highest preference value. ๐Ÿ”ฅ

It only does anything when there's a shim context on the socket. โœจ

By default the option value is NULL, meaning it's disabled. ๐Ÿซฅ

Like we said earlier, a locator's preference is a combo of priority and weight as per DNS SRV [RFC2782]. When there's more than one candidate destination locator, the shim sub-layer picks one based on the priority and weight given for each locator. It's literally a little popularity contest ๐Ÿ†

The data type is a pointer to the shim_locator information data structure, as defined in Section 8.1. ๐Ÿงš

If the app uses this on an unconnected socket, you get EOPNOTSUPP. If there's no shim context on the socket, you get ENOENT. ๐Ÿ’€

If the validation of the requested locator fails, you get EINVALIDLOCATOR. ๐Ÿ˜ญ

If the requested locator is found to be unreachable by a reachability check, you get EUNREACHABLELOCATOR. ๐Ÿฅบ

The usage is the same as SHIM_LOC_LOCAL_PREF. Easy peasy ๐Ÿ“


6.6. SHIM_LOC_LOCAL_RECV ๐ŸŽ€

SHIM_LOC_LOCAL_RECV lets an app ask the shim sub-layer to store the destination locator of the received IP packet in an ancillary data object. You can get to that object with recvmsg(). This option only works when there's a shim context on the socket. ๐Ÿงฉ

The data type is an integer. The option value MUST be binary (0 or 1). By default it's 0, which means the option is disabled. ๐Ÿ™…

You can set it with setsockopt() and read it with getsockopt(). ๐Ÿ’–

To learn how to access the locator info stored in those ancillary data objects, check out Section 7. ๐Ÿ‘€

If you use it on an unconnected socket, you get EOPNOTSUPP. If there's no shim context on the socket, you get ENOENT. ๐Ÿ’€

Here's how an app asks the shim sub-layer to store a destination locator:

    int optval;

    optval = 1;

    setsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_RECV, &optval,
               sizeof(optval));

And here's how an app gets the value:

    int optval;
    int len;

    len = sizeof(optval);

    getsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_RECV, &optval, &len);

6.7. SHIM_LOC_PEER_RECV ๐ŸŒท

SHIM_LOC_PEER_RECV asks the shim sub-layer to store the source locator of the received IP packet in an ancillary data object that you can access with recvmsg(). Again, this only works when there's a shim context on the socket. โœจ

The data type is an integer. The option value MUST be binary (0 or 1). By default it's 0, meaning the option is disabled. ๐Ÿ™…

You can set it with setsockopt() and read it with getsockopt(). ๐Ÿ’–

For the procedure to access the locator info in those ancillary data objects, see Section 7. ๐Ÿ‘€

If you use it on an unconnected socket, you get EOPNOTSUPP. If there's no shim context on the socket, you get ENOENT. ๐Ÿ’€

The usage is the same as SHIM_LOC_LOCAL_RECV, so you already know how to do it. ๐Ÿซถ๐Ÿ“

6.8. SHIM_LOC_LOCAL_SEND โœจ

okay so SHIM_LOC_LOCAL_SEND is how you tell the shim sub-layer "hey, use THIS locator as the source locator" for the IP packets going out of the socket ๐Ÿ’…. it's only effective if there's a shim context associated with the socket, so no context, no vibes ๐Ÿ™ˆ

the data type of the option value is a pointer to the shim_locator data structure ๐ŸŽ€

an app can set the local locator with setsockopt(), giving it a locator stored in a shim_locator data structure. if you pass a zero-filled locator, the old local locator setting gets inactivated ๐Ÿซถ

an app can get the local locator with getsockopt() ๐ŸŒธ

if the app sets this option on an unconnected socket, it gets error code EOPNOTSUPP back ๐Ÿ’€

if there's no shim context associated with the socket, it gets error code ENOENT ๐Ÿ˜ญ

and if the locator is invalid, you get error code EINVALIDLOCATOR ๐Ÿ™…โ€โ™€๏ธ

here's an example of an app asking the shim sub-layer to use a specific local locator with this option ๐Ÿ’–

    struct shim_locator locator;
    struct in6_addr ia6;

    /* an IPv6 address preferred for the source locator is copied
       to the parameter ia6 */

    memset(&locator, 0, sizeof(locator));

    /* fill shim_locator data structure */
    locator.lc_family = AF_INET6;
    locator.lc_ifidx = 0;
    locator.lc_flags = 0;
    locator.lc_prio = 0;
    locator.lc_weight = 0;
    memcpy(&locator.lc_addr, &ia6, sizeof(ia6));

    setsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_SEND, &locator,
               sizeof(locator));

and here's how an app gets the designated local locator back ๐Ÿฆ‹

    struct shim_locator locator;

    memset(&locator, 0, sizeof(locator));

    getsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_SEND, &locator,
               sizeof(locator));

    /* check locator */

6.9. SHIM_LOC_PEER_SEND ๐Ÿ’œ

okay this one is the destination version ๐Ÿ‘‘ SHIM_LOC_PEER_SEND asks the shim sub-layer to use a specific locator as the destination locator for IP packets sent from the socket. same rule as before: it only works when there's a shim context attached ๐Ÿงš

the data type of the option value is a pointer to the shim_locator data structure ๐ŸŽ€

an app can set the remote locator with setsockopt(), providing a locator stored in a shim_locator data structure. a zero-filled locator inactivates the pre-existing remote locator setting ๐Ÿซถ

an app can get the specified remote locator with getsockopt() ๐ŸŒธ

โš ๏ธ the difference between SHIM_LOC_PEER_SEND and SHIM_LOC_PEER_PREF is that SEND guarantees the use of a requested locator when applicable, whereas PREF does not. big deal, so pay attention ๐Ÿ˜ญ

the error codes are kind of a lot, so here's the rundown ๐Ÿ“

  • an unconnected socket gets error code EOPNOTSUPP ๐Ÿ’€
  • no shim context on the socket gets error code ENOENT ๐Ÿ™ˆ
  • a requested locator that fails validation gets error code EINVALIDLOCATOR ๐Ÿ™…โ€โ™€๏ธ
  • a requested locator whose reachability hasn't been verified yet gets error code EUNVERIFIEDLOCATOR ๐ŸŒˆ
  • a requested locator that a reachability check determines is unreachable gets error code EUNREACHABLELOCATOR ๐Ÿ’”

and the usage is the same as that of the SHIM_LOC_LOCAL_SEND option, so you already know how to do it ๐Ÿ’…


6.10. SHIM_LOCLIST_LOCAL ๐ŸŒท

so SHIM_LOCLIST_LOCAL lets you get or set the locator list tied to the local EID of the shim context on the socket ๐Ÿฆ‹ again, it only does anything when there's a shim context attached ๐Ÿงš

the data type of the option value is a pointer to the buffer where a locator list is stored. check out Section 8 for the data structure that stores the locator information ๐Ÿ“– by default the option value is NULL, which means the option is disabled ๐Ÿ™ˆ

an app can get the locator list with getsockopt(). the buffer pointed to by the optval argument SHOULD be large enough to store an array of locator information ๐ŸŽ€ the thing is, the number of locator information items isn't known beforehand, so it's kind of a guessing game ๐Ÿ˜ญ

the local locator list can be set with setsockopt(). the buffer pointed to by the optval argument MUST contain an array of locator structures ๐Ÿซถ non-negotiable, bestie ๐Ÿ‘‘

if the app uses this on an unconnected socket, it gets error code EOPNOTSUPP ๐Ÿ’€

no shim context on the socket means error code ENOENT ๐Ÿ˜ญ

if validation fails for any of the specified locators, you get error code EINVALIDLOCATOR ๐Ÿ™…โ€โ™€๏ธ

and error code ETOOMANYLOCATORS shows up when the number of locators goes over the limit (SHIM_MAX_LOCATORS), or when the app's buffer isn't big enough to hold the locator list the shim sub-layer gives back ๐Ÿ“

here's a set example. heads up that an IPv4 locator can be handled by HIP and not by Shim6, which is a very real plot twist ๐ŸŒˆ

    struct shim_locator locators[SHIM_MAX_LOCATORS];
    struct sockaddr_in *sin;
    struct sockaddr_in6 *sin6;

    memset(locators, 0, sizeof(locators));

    ...

    /* obtain local IP addresses from local interfaces */

    ...

    /* first locator (an IPv6 address) */
    locators[0].lc_family = AF_INET6;
    locators[0].lc_ifidx = 0;
    locators[0].lc_flags = 0;
    locators[0].lc_prio = 1;
    locators[0].lc_weight = 0;
    memcpy(&locators[0].lc_addr, &sa6->sin6_addr,
           sizeof(sa6->sin6_addr));

    ...

    /* second locator (an IPv4 address) */
    locators[1].lc_family = AF_INET;
    locators[1].lc_ifidx = 0;
    locators[1].lc_flags = 0;
    locators[1].lc_prio = 0;
    locators[1].lc_weight = 0;
    memcpy(&locators[1].lc_addr, &sa->sin_addr,
           sizeof(sa->sin_addr));

    setsockopt(fd, SOL_SHIM, SHIM_LOCLIST_LOCAL, locators,
               sizeof(locators));

and here's how you get the list of locators tied to the local EID ๐Ÿงš

    struct shim_locator locators[SHIM_MAX_LOCATORS];

    memset(locators, 0, sizeof(locators));

    getsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_RECV, locators,
               sizeof(locators));

    /* parse locators */
    ...

6.11. SHIM_LOCLIST_PEER ๐ŸŒธ

okay this is the peer-side twin of the last one ๐Ÿ‘ฏโ€โ™€๏ธ SHIM_LOCLIST_PEER gets or sets the locator list tied to the peer EID of the shim context on the socket. yep, you guessed it, it's only effective when there's a shim context attached ๐Ÿ’…

the data type of the option value is a pointer to the buffer where a locator list is stored. Section 8 has the data structure for storing the locator information ๐Ÿ“– by default the option value is NULL, so the option is disabled ๐Ÿ™ˆ

an app can get the locator list with getsockopt(). the buffer pointed to by the optval argument SHOULD be large enough to store an array of locator information ๐ŸŽ€ and yes, the number of locator information items isn't known beforehand, so, again, a little guesswork ๐Ÿ˜ญ

an app can set the locator list with setsockopt(). the buffer pointed to by the optval argument MUST contain an array of locator list items ๐Ÿซถ

on an unconnected socket, the app gets error code EOPNOTSUPP ๐Ÿ’€

no shim context means error code ENOENT ๐Ÿ˜ญ

if validation fails for any of the specified locators, it's error code EINVALIDLOCATOR ๐Ÿ™…โ€โ™€๏ธ

if the requested locator's reachability hasn't been verified yet, it's error code EUNVERIFIEDLOCATOR ๐ŸŒˆ

if a reachability check says the requested locator is unreachable, it's error code EUNREACHABLELOCATOR ๐Ÿ’”

and error code ETOOMANYLOCATORS pops up when the number of locators goes over SHIM_MAX_LOCATORS, or when the app's buffer is too small for the locator list the shim sub-layer hands back ๐Ÿ“

the usage is the same as SHIM_LOCLIST_LOCAL, so no new moves to learn ๐Ÿฆ‹


6.12. SHIM_APP_TIMEOUT โญ

SHIM_APP_TIMEOUT is how you get or set the Send Timeout value of REAP [RFC5534] ๐Ÿงš it only works when there's a shim context attached to the socket, you know the drill ๐Ÿ’…

the data type of the option value is an integer ๐ŸŽ€ the value is the timeout period in seconds for sending a REAP Keepalive message since the last outbound traffic ๐Ÿซถ by default the option value is 0, which means the option is disabled ๐Ÿ™ˆ when it's disabled, REAP just uses its default Send Timeout value as specified in [RFC5534] ๐ŸŒธ

on an unconnected socket, the app gets error code EOPNOTSUPP ๐Ÿ’€

no shim context means error code ENOENT ๐Ÿ˜ญ

and if there's no REAP instance on the system, you get error code EOPNOTSUPP too ๐ŸŒˆ

here's an example of setting the timeout ๐Ÿ“

    int optval;

    optval = 15; /* 15 seconds */

    setsockopt(fd, SOL_SHIM, SHIM_APP_TIMEOUT, &optval,
               sizeof(optval));

and here's how you get the timeout value back ๐Ÿฆ‹

    int optval;
    int len;

    len = sizeof(optval);

    getsockopt(fd, SOL_SHIM, SHIM_APP_TIMEOUT, &optval, &len);

6.13. SHIM_PATHEXPLORE ๐Ÿ”ฅ

okay, path exploration is when you go looking for an alternative locator pair to your current one ๐Ÿ—บ๏ธ as the REAP specification defines, a peer may send Probe messages to find that alternative pair ๐Ÿงš and this socket option is where an app can get or set parameters for all of that ๐Ÿ’…

the application MAY use this socket option to get or set parameters concerning path exploration ๐Ÿ‘‘ totally optional, but iconic if you do ๐Ÿ’–

it's only effective when there's a shim context associated with the socket ๐ŸŽ€

the data type of the option value is a pointer to the buffer where a set of path exploration information is stored. the data structure is defined in Section 8 ๐Ÿ“–

by default the option value is NULL, meaning the option is disabled ๐Ÿ™ˆ

an unconnected socket gets error code EOPNOTSUPP ๐Ÿ’€

and no shim context on the socket gets error code ENOENT ๐Ÿ˜ญ

here's an example of setting path exploration parameters ๐Ÿซถ

    struct shim6_pathexplore pe;

    pe.pe_probenum = 4;        /* times */
    pe.pe_keepaliveto = 10;    /* seconds */
    pe.pe_initprobeto = 500;   /* milliseconds */
    pe.pe_reserved = 0;

    setsockopt(fd, SOL_SHIM, SHIM_PATHEXPLORE, &pe, sizeof(pe));

and here's how you get them back ๐ŸŒˆ

    struct shim6_pathexplore pe;
    int len;

    len = sizeof(pe);

    getsockopt(fd, SOL_SHIM, SHIM_PATHEXPLORE, &pe, &len);

6.14. SHIM_DEFERRED_CONTEXT_SETUP โœจ

okay so this option is how you check whether deferred context setup is possible ๐Ÿ” basically the context gets set up at the same time as the data communication, like both are happening in parallel ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ ngl that's kinda iconic. Shim6 supports deferred context setup, but HIP doesn't, because EIDs in HIP (aka Host Identifiers) are non-routable ๐Ÿ™…โ€โ™€๏ธ not me being dramatic, that's just the rule ๐Ÿ’…

Also, this socket option is read-only, so you can only read the value with getsockopt() ๐Ÿ‘€

The data type for the option value is an integer ๐Ÿ”ข and it MUST be binary, so either 0 or 1 ๐ŸŽ€ A value of 1 means the shim sub-layer supports deferred context setup, and that's the main thing you're looking for โœจ

If an application sets this option on an unconnected socket, it gets error code EOPNOTSUPP back ๐Ÿ™ˆ

here's how an app can check if deferred context setup is possible:

       int optval;
       int len;

       len = sizeof(optval);

       getsockopt(fd, SOL_SHIM, SHIM_DEFERRED_CONTEXT_SETUP,
                  &optval, &len);

6.15. Applicability ๐Ÿงš

bestie, every socket option in this section is for connected sockets ๐Ÿ”— except for SHIM_DONTSHIM, which is the exception to the exception ๐Ÿ’œ

also, all the options here EXCEPT SHIM_ASSOCIATED, SHIM_DONTSHIM, and SHIM_CONTEXT_DEFERRED_SETUP only do something if there's a shim context attached to the socket ๐Ÿซถ no context, no effect, it's that simple ๐Ÿ˜ญ


6.16. Error Handling ๐Ÿšจ

if it works, getsockopt() and setsockopt() return 0 ๐ŸŽ‰ if it doesn't, they return -1 and set errno so you know what went wrong ๐Ÿ’€

there are also some new error values for certain shim-specific options, which basically means "it didn't finish all the way" ๐Ÿฅฒ

  • EINVALIDLOCATOR: the locator isn't part of the HBA set [RFC5535] inside the shim context attached to the socket ๐Ÿ™…โ€โ™€๏ธ
  • EUNVERIFIEDLOCATOR: the reachability of the locator hasn't been confirmed yet. this one only applies to the peer's locator ๐Ÿ•ต๏ธโ€โ™€๏ธ
  • EUNREACHABLELOCATOR: the locator isn't reachable according to the reachability check. again, this is only for the peer's locator ๐Ÿ˜ค

7. Ancillary Data for Multihoming Shim Sub-Layer ๐Ÿฆ‹

this section defines the ancillary data used for locator management and notifications going from the shim sub-layer to the app, and from the app to the shim sub-layer ๐Ÿ“ฌโœจ

when an app does locator management with sendmsg() or recvmsg(), the msg_control member of the msghdr structure (see Figure 3) holds a pointer to a buffer where one or more shim-specific ancillary data objects can live ๐Ÿ—‚๏ธ each ancillary data object can store a single locator ๐Ÿ“ and it should be possible to process these objects with the existing macros from POSIX and [RFC3542] ๐ŸŒธ

        struct msghdr {
                caddr_t msg_name;       /* optional address */
                u_int   msg_namelen;    /* size of address */
                struct  iovec *msg_iov; /* scatter/gather array */
                u_int   msg_iovlen;     /* # elements in msg_iov */
                caddr_t msg_control;    /* ancillary data, see below */
                u_int   msg_controllen; /* ancillary data buffer len */
                int     msg_flags;      /* flags on received message */
        };

Figure 3: msghdr Structure

if the socket is unconnected, msg_name stores the socket address of the peer ๐Ÿ‘€ but heads up: that address is the peer's identifier, NOT its locator ๐Ÿ™ˆ if you want the peer's locator, use SHIM_LOC_PEER_RECV instead ๐Ÿ”‘

Table 2 lists the shim-specific ancillary data you can use for locator management with recvmsg() or sendmsg() ๐Ÿ“‹ in every case, cmsg_level MUST be set to SOL_SHIM ๐Ÿ’…

     +---------------------+-----------+-----------+-----------------+
     | cmsg_type           | sendmsg() | recvmsg() |   cmsg_data[]   |
     +---------------------+-----------+-----------+-----------------+
     | SHIM_LOC_LOCAL_RECV |           |     o     |      Note 1     |
     | SHIM_LOC_PEER_RECV  |           |     o     |      Note 1     |
     | SHIM_LOC_LOCAL_SEND |     o     |           |      Note 1     |
     | SHIM_LOC_PEER_SEND  |     o     |           |      Note 1     |
     | SHIM_FEEDBACK       |     o     |           | shim_feedback{} |
     +---------------------+-----------+-----------+-----------------+

Table 2: Shim-Specific Ancillary Data

Note 1: cmsg_data[] within msg_control includes a single sockaddr_in{} or sockaddr_in6{} and padding if necessary ๐Ÿง


7.1. Get Locator from Incoming Packet ๐Ÿ“ฅ

an app can grab locator info from an incoming IP packet by turning on the shim-specific socket options for the socket โœจ if SHIM_LOC_LOCAL_RECV and/or SHIM_LOC_PEER_RECV are set, the app can pull a local and/or remote locator out of the ancillary data ๐Ÿซง

if there's no shim context attached to the socket, the shim sub-layer MUST return zero-filled locator info to the app ๐Ÿฅน


7.2. Set Locator for Outgoing Packet ๐Ÿ“ค

an app can choose which locators get used for sending an IP packet, using sendmsg() ๐ŸŽฏ when the ancillary data has a cmsg_type of SHIM_LOC_LOCAL_SEND and/or SHIM_LOC_PEER_SEND, the app can explicitly pick the source and/or destination locators for communication over the socket ๐Ÿ’– if the locator pair checks out as verified, the shim sub-layer overrides the locator(s) on the outgoing IP packet ๐Ÿ”ฅ just know the effect only lasts for the one datagram sent by that sendmsg() โฑ๏ธ

no shim context attached? you get error code ENOENT ๐Ÿ˜ญ

EINVALIDLOCATOR comes back when validating the locator fails ๐Ÿ™…โ€โ™€๏ธ

EUNVERIFIEDLOCATOR comes back when reachability for the requested locator hasn't been verified yet ๐Ÿ•ต๏ธโ€โ™€๏ธ the app is recommended to use a different destination locator until the reachability check for the requested one is done ๐Ÿฆ‹

EUNREACHABLELOCATOR comes back when the requested locator is determined to be unreachable by a reachability check ๐Ÿ’€ the app is recommended to use a different destination locator when it gets this error ๐ŸŒˆ


7.3. Notification from Application to Multihoming Shim Sub-Layer ๐Ÿ“ฃ

an app MAY give the shim sub-layer feedback about how the communication is going ๐Ÿซถ this is super useful because it helps the shim sub-layer keep an eye on whether the locator pair currently in use is still reachable within a given shim context ๐Ÿ‘๏ธ

the notification gets sent with sendmsg() by specifying a new ancillary data type called SHIM_FEEDBACK ๐ŸŽ€ you handle it by putting SHIM_FEEDBACK in cmsg_type โœจ

no shim context attached to the socket? error code ENOENT again ๐Ÿ˜ค

check Section 8.3 for the details of the data structure to use ๐Ÿ“š

it's outside the scope of this document to describe how the shim sub-layer would react when an app gives it feedback ๐Ÿ™ˆ so that's a whole other conversation, bestie

7.4. Applicability ๐ŸŒŸ

all the ancillary data for the shim sub-layer applies to connected sockets ๐Ÿ”—

okay, real talk: care is needed when you use SHIM_LOC_*_RECV on stream-oriented sockets (like TCP sockets) ๐Ÿ˜ฌ there's no one-to-one mapping between a single send or receive operation and the data being received (like a TCP segment), so there's no guarantee that the locator(s) in the SHIM_LOC_*_RECV ancillary data are the same as the ones showing up in the IP packets received ๐ŸŒ€ the shim sub-layer SHOULD provide the latest locator information to the app in response to the SHIM_LOC_*_RECV socket option ๐Ÿ’œ


8. Data Structures ๐Ÿ“

this section gives the data structures for the shim sub-layer ๐Ÿงš these get used either as a parameter for setsockopt() or getsockopt() (see Section 6), or as a parameter for ancillary data processed by sendmsg() or recvmsg() (see Section 7) ๐Ÿ’…


8.1. Data Structure for Locator Information ๐Ÿ—บ๏ธ

as defined in Section 6, the SHIM_LOC_*_PREF, SHIM_LOC_*_SEND, and SHIM_LOCLIST_* socket options need to handle one or more pieces of locator information ๐Ÿ“ and locator info isn't just the locator itself, it also includes extra details about the locator that are useful for locator management ๐Ÿซง so a new data structure was made just to hold that info ๐ŸŽ€

here's shim_locator, the struct that stores locator information โœจ

        struct shim_locator {
                uint8_t    lc_family;       /* address family */
                uint8_t    lc_proto;        /* protocol */
                uint16_t   lc_port;         /* port number */
                uint16_t   lc_prio;         /* preference value */
                uint16_t   lc_weight;       /* weight */
                uint32_t   lc_ifidx;        /* interface index */
                struct in6_addr lc_addr;    /* address */
                uint16_t   lc_flags;        /* flags */
        };

Figure 4: Shim Locator Structure

here's what each field means, bestie ๐Ÿซถ

  • lc_family: the address family of the locator (like AF_INET, AF_INET6) ๐ŸŒ it is required that this parameter contains a non-zero value that indicates the exact address family of the locator ๐Ÿ”ข
  • lc_proto: the Internet Protocol number for the protocol used to handle a locator behind a NAT ๐Ÿงฑ the value MUST be set to zero when there is no NAT involved ๐Ÿ™…โ€โ™€๏ธ when the locator is behind a NAT, the value MUST be set to IPPROTO_UDP ๐ŸŒธ
  • lc_port: the port number used for handling a locator behind a NAT ๐Ÿšช
  • lc_prio: the priority of the locator ๐Ÿ‘‘ the range is 0-65535, and the lowest priority value means the highest priority ๐Ÿ™ƒ (wild, I know)
  • lc_weight: a relative weight for locators with the same priority value โš–๏ธ the range is 0-65535, and a locator with a higher weight value is prioritized over the other locators with lower weight values ๐Ÿ’–
  • lc_ifidx: the interface index of the network interface the locator is assigned to ๐Ÿ”Œ this field only applies to local locators and has no effect in set operations ๐Ÿซง
  • lc_addr: contains the locator ๐Ÿ“ฎ for IPv4, the locator MUST be formatted as an IPv4-mapped IPv6 address, as defined in [RFC4291] ๐Ÿฆ‹ and the locator MUST be stored in network byte order ๐Ÿ”ฅ
  • lc_flags: each bit of the flags represents a specific characteristic of the locator ๐ŸŒˆ the Hash-Based Address (HBA) is defined as 0x01, and the Cryptographically Generated Address (CGA) is defined as 0x02 ๐Ÿ” this field has no effect in set operations ๐Ÿฅฑ

8.1.1. Handling Locator behind NAT โœจ

okay so the locator information is allowed to MAY contain a locator behind a Network Address Translator (NAT) ๐ŸŒธ wait, let me say that properly: the locator information MAY contain a locator behind a NAT. This can happen when the host sits behind the NAT and uses a local address as its source locator to talk to the peer. Also, a NAT traversal mechanism for HIP exists, and it lets a HIP host tunnel control and data traffic over UDP [RFC5770]. Bestie, the locator behind a NAT is not necessarily an IPv4 address. It can be an IPv6 address too ๐Ÿ’…

Here's an example where the application sets a UDP encapsulation interface as the source locator when it sends IP packets ๐Ÿฆ‹

          struct shim_locator locator;
          struct in6_addr ia6;

          /* copy the private IPv4 address to the ia6 as an IPv4-mapped
             IPv6 address */

          memset(&locator, 0, sizeof(locator));

          /* fill shim_locator data structure */
          locator.lc_family = AF_INET;
          locator.lc_proto = IPPROTO_UDP;
          locator.lc_port = 50500;
          locator.lc_ifidx = 0;
          locator.lc_flags = 0;
          locator.lc_prio = 0;
          locator.lc_weight = 0;

          memcpy(&locator.lc_addr, &ia6, sizeof(ia6));

          setsockopt(fd, SOL_SHIM, SHIM_LOC_LOCAL_SEND, &locator,
                     sizeof(locator));

Figure 5: Handling Locator behind NAT ๐ŸŽ€


8.2. Path Exploration Parameter ๐Ÿฆ‹

okay so, as defined in Section 6, SHIM_PATHEXPLORE lets an application set or read the parameters for path exploration and failure detection ๐Ÿ’– There's a new data structure called shim_pathexplore that stores everything you need. You can pass it to getsockopt() or setsockopt() as an argument. Here's the layout ๐Ÿ‘‘

        struct shim_pathexplore {
                uint16_t  pe_probenum;      /* # of initial probes */
                uint16_t  pe_keepaliveto;   /* Keepalive Timeout */
                uint16_t  pe_keepaliveint;  /* Keepalive Interval */
                uint16_t  pe_initprobeto;   /* Initial Probe Timeout */
                uint32_t  pe_reserved;      /* reserved */
        };

Figure 6: Path Explore Structure โœจ

Here's what each field does, babe ๐Ÿงš

pe_probenum: This is the number of initial Probe messages to be sent. The value MUST be set as per [RFC5534].

pe_keepaliveto: This is the timeout value in seconds for detecting a failure when the host doesn't receive any packets for a certain period while there is outbound traffic ๐Ÿ˜ญ When the timer goes off, the path exploration procedure runs by sending a REAP Probe message. The value MUST be set as per [RFC5534].

pe_keepaliveint: This is the interval, in seconds, between REAP Keepalive messages that the host sends when there's no outbound traffic to the peer host ๐ŸŒˆ The value MUST be set as per [RFC5534].

pe_initprobeto: This is the retransmission timer of the REAP Probe message, in milliseconds. This timer is applied before exponential back-off starts. A REAP Probe message for the same locator pair may be retransmitted ๐Ÿ“ The value MUST be set as per [RFC5534].

pe_reserved: A reserved field for future extension. By default, the field MUST be initialized to zero ๐Ÿซถ


8.3. Feedback Information ๐Ÿ’œ

As mentioned in Section 7.3, applications can tell the shim sub-layer about the status of unicast reachability of the locator pair that's currently in use ๐Ÿ”ฅ This feedback goes through ancillary data called SHIM_FEEDBACK. There's a new data structure named shim_feedback, shown here ๐ŸŽ€

        struct shim_feedback {
                uint8_t   fb_direction;    /* direction of traffic */
                uint8_t   fb_indicator;    /* indicator (1-3) */
                uint16_t  fb_reserved;     /* reserved */
        };

Figure 7: Feedback Information Structure ๐Ÿ’…

fb_direction: This shows the direction of reachability between the locator pair in question. A value of 0 means the outbound direction, and a value of 1 means the inbound direction ๐Ÿฆ‹

fb_indicator: This is a value that shows how satisfied the application is with the unidirectional reachability for a given locator pair. Here's the breakdown ๐ŸŒธ

  • 0: Default value. Whenever this value is specified, the feedback information MUST NOT be processed by the shim sub-layer. ๐Ÿ™ˆ
  • 1: Unable to connect. There is no unidirectional reachability between the locator pair in question. ๐Ÿ’€
  • 2: Unsatisfactory. The application is not satisfied with the unidirectional reachability between the locator pair in question. ๐Ÿ˜ญ
  • 3: Satisfactory. There is satisfactory unidirectional reachability between the locator pair in question. ๐ŸŒŸ

fb_reserved: Reserved field. It MUST be ignored by the receiver ๐Ÿงš


9. System Requirements ๐ŸŽ€

As addressed in Section 6, most of the socket options and ancillary data defined in this document apply to connected sockets. The kernel is assumed to be capable of keeping track of the association between a connected socket and a shim context. This requirement is considered reasonable because a pair of source and destination IP addresses is bound to a connected socket ๐Ÿ’–


10. Relation to Existing Sockets API Extensions ๐Ÿฆ‹

This section explains how the sockets API defined in this document relates to the existing sockets API extensions ๐ŸŒˆ

As mentioned in Section 6, the basic assumption is that the existing sockets API keeps working above the shim sub-layer. In other words, the existing sockets API deals with identifiers, while the sockets API defined in this document deals with locators ๐Ÿงš

SHIM_LOC_LOCAL_SEND and SHIM_LOC_PEER_SEND socket options are semantically similar to the IPV6_PKTINFO sockets API, in the sense that both give an application a way to set the source IP address of outbound IP packets ๐Ÿ’…

SHIM_LOC_LOCAL_RECV and SHIM_LOC_PEER_RECV socket options are semantically similar to the IP_RECVDSTADDR and IPV6_PKTINFO sockets APIs, in the sense that both give an application a way to get the source and/or destination IP address of inbound IP packets ๐Ÿ“

getsockname() and getpeername() let an application get the "name" of the communication endpoints. That name is a pair of IP addresses and port numbers assigned to the socket. getsockname() gives the IP address and port number assigned to the socket on the local side, and getpeername() gives the IP address and port number of the peer side ๐Ÿซถ


11. Operational Considerations โœจ

This section gives operational considerations for the sockets API defined in this document ๐Ÿ‘‘

11.1. Conflict Resolution ๐Ÿ”ฅ

Okay, so conflicts can happen when different applications specify different preferences for the same shim context. For example, say applications A and B both talk to the same EID pair, but they each want a different local locator. The notion of context forking in Shim6 can sort out that conflict ๐Ÿ’€

It's possible that the socket options defined in Section 6 cause a conflict when the target context is shared by multiple applications. In that case, the socket handler should tell the shim sub-layer that context forking is required. In Shim6, when a context is forked, a unique identifier called the Forked Instance Identifier (FII) is assigned to the newly forked context. The forked context is then exclusively associated with the socket through which a non-default preference value was specified ๐Ÿฆ‹ The shim sub-layer keeps the forked context around for the lifetime of the associated socket instance. When the socket is closed, the shim sub-layer SHOULD delete the associated context ๐ŸŒธ

When an application specifies SHIM_LOC_*_SEND with a different source or destination locator that does not have the highest priority and weight given by SHIM_LOC_*_PREF, the shim sub-layer SHOULD supersede the request made by SHIM_LOC_*_SEND in favour of the preference specified by SHIM_LOC_*_PREF ๐Ÿ’–

When the peer provides preferences for its locators (for example, a Shim6 peer sends a locator with a Locator Preferences Option) and those conflict with preferences the application set through either SHIM_LOC_PEER_SEND or SHIM_LOC_PEER_PREF, the shim sub-layer SHOULD supersede the application's preferences in favour of the peer's preferences ๐Ÿ™ˆ

11.2. Incompatibility between IPv4 and IPv6 ๐ŸŒˆ

The shim sub-layer does identifier/locator adaptation. So in some cases, the whole IP header can be replaced with a new IP header of a different address family (for example, converting from IPv4 to IPv6 or the other way around) ๐Ÿ˜ญ That raises the question of how to make the conversion with minimum impact. This issue is common to other protocol conversion techniques [RFC2765] [RFC6145] ๐Ÿงš

As studied in earlier work on protocol conversion [RFC2765], [RFC6145], some features from IPv6 are not convertible to IPv4. These are IPv6 routing headers, hop-by-hop extension headers, and destination headers. Also, the notion of source routing isn't exactly the same in IPv4 and IPv6. This means an error may occur while converting the identifier and locator. Describing how the shim sub-layer should behave in those erroneous cases is outside the scope of this document ๐Ÿ’…


12. IANA Considerations ๐ŸŽ€

There are no IANA considerations for the socket options (SHIM_*), the ancillary data, and the socket level (SOL_SHIM) defined in this document. All the numbers concerned are not under the control of the IETF or IANA. They're platform-specific instead ๐ŸŒธ


13. Protocol Constant ๐Ÿ‘‘

This section defines a protocol constant ๐Ÿฆ‹

SHIM_MAX_LOCATORS: This is the maximum number of locators that can be included in a locator list. The value is set to 32 ๐Ÿ’–


14. Security Considerations ๐Ÿ’€

This section gives security considerations for the API defined in this document. Pay attention, this part is serious ๐Ÿ”ฅ

14.1. Treatment of Unknown Locator ๐Ÿ™ˆ

When sending IP packets, an application might request the use of an unknown locator for the source and/or destination locators. The treatment of an unknown locator can be a security concern, because using an invalid source and/or destination locator may cause a redirection attack ๐Ÿ˜ญ

14.1.1. Treatment of Unknown Source Locator ๐ŸŒŸ

The shim sub-layer checks whether the requested locator is available on any local interface. If it isn't, the shim sub-layer MUST reject the request and return an error message with the EINVALIDLOCATOR code to the application ๐Ÿ’€ If the locator is confirmed to be available, the shim sub-layer SHOULD initiate the procedure to update the locator list ๐Ÿซถ

Using the following socket options and ancillary data requires treatment of an unknown source locator ๐Ÿงš

  • SHIM_LOC_LOCAL_SEND
  • SHIM_LOC_LOCAL_PREF
  • SHIM_LOCLIST_LOCAL

14.1.2. Treatment of Unknown Destination Locator

okay so this one is about what happens when the destination locator is one nobody has heard of before ๐Ÿ™ˆ

if the shim sub-layer turns out to be Shim6, the Shim6 layer MUST reject the request for using an unknown destination locator. no cap, that's a hard no ๐Ÿšซ

if the shim sub-layer turns out to be HIP, the HIP layer MUST reject the request too ๐Ÿ’€ BUT there's an exceptional case ๐Ÿ‘€ where the HIP layer SHOULD accept it, provided the HIP association is in the UNASSOCIATED state โœจ (the details of locator handling in HIP are in Section 4.6 of [RFC6317], so go read that if you're curious ๐Ÿงš)

using these socket options and ancillary data requires treatment of an unknown destination locator:

  • SHIM_LOC_PEER_SEND
  • SHIM_LOC_PEER_PREF
  • SHIM_LOCLIST_PEER

15. Acknowledgments ๐Ÿซถ

the authors want to thank Jari Arkko, who joined the discussion that led to the first version of this doc ๐Ÿ’œ and Tatuya Jinmei, who reviewed the early draft super thoroughly and gave detailed notes on sockets API issues ๐Ÿ™Œ Thomas Henderson also gave super valuable comments, especially from the HIP side ๐Ÿฆ‹

the authors also sincerely thank these people for their helpful comments on the document: Samu Varjonen, Dmitriy Kuptsov, Brian Carpenter, Michael Scharf, Sebastien Barre, and Roni Even ๐ŸŒธโœจ


16. References ๐Ÿ“š

16.1. Normative References

   [POSIX]     "IEEE Std. 1003.1-2008 Standard for Information
               Technology -- Portable Operating System Interface
               (POSIX).  Open group Technical Standard: Base
               Specifications, Issue 7", September 2008,
               <http://www.opengroup.org/austin>.

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

   [RFC3542]   Stevens, W., Thomas, M., Nordmark, E., and T.  Jinmei,
               "Advanced Sockets Application Program Interface (API) for
               IPv6", RFC 3542, May 2003.

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

   [RFC5533]   Nordmark, E. and M. Bagnulo, "Shim6: Level 3 Multihoming
               Shim Protocol for IPv6", RFC 5533, June 2009.

   [RFC5534]   Arkko, J. and I. van Beijnum, "Failure Detection and
               Locator Pair Exploration Protocol for IPv6 Multihoming",
               RFC 5534, June 2009.

16.2. Informative References

   [RFC2765]   Nordmark, E., "Stateless IP/ICMP Translation Algorithm
               (SIIT)", RFC 2765, February 2000.

   [RFC2782]   Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for
               specifying the location of services (DNS SRV)", RFC 2782,
               February 2000.

   [RFC4291]   Hinden, R. and S. Deering, "IP Version 6 Addressing
               Architecture", RFC 4291, February 2006.

   [RFC5535]   Bagnulo, M., "Hash-Based Addresses (HBA)", RFC 5535,
               June 2009.

   [RFC5770]   Komu, M., Henderson, T., Tschofenig, H., Melen, J., and
               A. Keranen, Ed., "Basic Host Identity Protocol (HIP)
               Extensions for Traversal of Network Address Translators",
               RFC 5770, April 2010.

   [RFC6145]   Li, X., Bao, C., and F. Baker, "IP/ICMP Translation
               Algorithm", RFC 6145, April 2011.

   [RFC6317]   Komu, M. and T. Henderson, "Basic Socket Interface
               Extensions for the Host Identity Protocol (HIP)",
               RFC 6317, July 2011.

   [SHIM6-APP-REFER]
               Nordmark, E., "Shim6 Application Referral Issues", Work
               in Progress, July 2005.

Appendix A. Context Forking โœจ

okay this appendix is about context forking and how it links up with the multihoming shim API ๐Ÿ”ฅ

so Shim6 supports the notion of context forking ๐Ÿงš a peer might decide to fork a context for some reason (like, an upper-layer protocol wants a different locator pair than the one in an available context). the whole thing works a lot like normal context establishment, with the 4-way message exchange ๐Ÿ’… the peer that decides to fork is the one that starts the context establishment, and we call it the "initiator" ๐ŸŽ€ its peer is the "responder" ๐ŸŒˆ

once the forked context is set up between the two peers, the initiator can apply the forked context to the packet flow, because the system keeps an association between the forked context and the socket that the application asked for the fork on ๐Ÿฆ‹ how that association gets maintained is an implementation-specific issue, so it's up to whoever builds it ๐Ÿ› ๏ธ but on the responder side it gets messy ๐Ÿ˜ญ there's a question of how outbound packets get multiplexed by the shim sub-layer, since more than one Shim6 context matches the ULID pair of the packet flow. so there's a need to tell packet flows apart not just by the ULID pairs but by some other information, and to link a given flow to one specific context ๐Ÿ‘€

Figure 8 shows a scenario where two peers fork a context ๐ŸŽฌ at first there's one transaction between them, from application 1 (App1). then another transaction starts, from application 2 (App2). both transactions use the same ULID pair. the first context pair (Ctx1) is set up for App1's transaction. when App2 makes its requests, the shim sub-layer on Peer 1 decides to fork a context, so a forked context (Ctx2) gets set up between the peers, and it should be used only for App2's transaction ๐Ÿ’– ideally, the multiplexing and demultiplexing of packet flows for App1 and App2 would happen exactly as the figure shows. but like we said earlier, the responder still has to multiplex the outbound flows of App1 and App2 somehow ๐Ÿ˜ต also, if a context forking happens on the initiator side, a context forking also needs to happen on the responder side โญ

              Peer 1                                 Peer 2
            (initiator)                            (responder)

       +----+         +----+                  +----+         +----+
       |App1|         |App2|                  |App1|         |App2|
       +----+         +----+                  +----+         +----+
         |^             |^                      ^|             ^|
         v|             v|                      |v             |v
    -----S1-------------S2-----            -----S1-------------S2-----
         ||             ||                      ||             ||
         ||             ||                      ||             ||

        Ctx1           Ctx2                    Ctx1           Ctx2
    ULID:<A1,B1>   ULID:<A1,B1>            ULID:<B1,A1>    ULID:<B1,A1>
    Loc: <A1,B2>   Loc: <A1,B3>            Loc: <B2,A1>    Loc: <B3,A1>
    FII: 0         FII: 100                FII: 0          FII: 100

         |^             |^                      ^|             ^|
         ||             ||                      ||             ||
         ||             ||                      ||             ||
         \..............||....................../|             ||
          \.............||......................./             ||
                        ||                                     ||
                        \|...................................../|
                         \....................................../

                         Figure 8: Context Forking

how to solve the issue described above is a topic for further study ๐Ÿ”๐Ÿง 


Authors' Addresses ๐ŸŽ€

   Miika Komu
   Aalto University
   Espoo
   Finland

   Phone: +358505734395
   Fax:   +358947025014
   EMail: miika@iki.fi
   URI:   http://cse.aalto.fi/research/groups/datacommunications/people/


   Marcelo Bagnulo
   Universidad Carlos III de Madrid
   Av. Universidad 30
   Leganes  28911
   SPAIN

   Phone: +34 91 6248837
   EMail: marcelo@it.uc3m.es
   URI:   http://it.uc3m.es/marcelo


   Kristian Slavov
   Ericsson Research Nomadiclab
   Hirsalantie 11
   Jorvas  FI-02420
   Finland

   Phone: +358 9 299 3286
   EMail: kristian.slavov@ericsson.com


   Shinta Sugimoto (editor)
   Nippon Ericsson K.K.
   Koraku Mori Building
   1-4-14, Koraku, Bunkyo-ku
   Tokyo  112-0004
   Japan

   Phone: +81 3 3830 2241
   EMail: shinta.sugimoto@ericsson.com
๐Ÿ“ฆ where this page comes from