RFC 6316
Sockets Application Program Interface (API) for Multihoming Shim
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 Notice ๐
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:
- 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 ๐ฅน
- With the newly defined shim socket options, the app gets extra control over locator management ๐
- The shim-specific options can stay independent from the address family (
IPPROTO_IPorIPPROTO_IPV6) and the transport protocol (IPPROTO_TCPorIPPROTO_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_SENDSHIM_LOC_LOCAL_PREFSHIM_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_SENDSHIM_LOC_PEER_PREFSHIM_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
- ietf: rfc6316 2011-07
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms