Draft: draft-ietf-quic-load-balancers

Commentary: Fixes the broken bits in and also extends to encrypted algorithms ( fixing ) 
 In principle , the low - config algorithm 's method of extracting a server ID can be extended to all the algorithms . Thus the " server ID allocation method " would be an independent variable , with value ' dynamic ' and ' static ' , and the algorithms could operate with either method . This is a significant refactor of the routing section , but will make future decisions about static / dynamic much cleaner to discuss .
In QUIC-LB, load balancers do not generate individual connection IDs
to servers.  Instead, they communicate the parameters of an algorithm
to generate routable connection IDs.
The DCID might not be long enough for the routing algorithm to
process.
The config rotation bits (config-rotation) may not correspond to
an active configuration.
Load balancers MUST forward packets with long headers and non-
compliant DCIDs to an active server using an algorithm of its own
choosing.  It need not coordinate this algorithm with the servers.
The algorithm SHOULD be deterministic over short time scales so that
related packets go to the same server.  The design of this algorithm
SHOULD consider the version-invariant properties of QUIC described in
QUIC-INVARIANTS to maximize its robustness to future versions of
QUIC.  For example, a non-compliant DCID might be converted to an
integer and divided by the number of servers, with the modulus used
to forward the packet.  The number of servers is usually consistent
on the time scale of a QUIC connection handshake.  See also version-
invariance.
As a partial exception to the above, load balancers MAY drop packets
with long headers and non-compliant DCIDs if and only if it knows
that the encoded QUIC version does not allow a non-compliant DCID in
a packet with that signature.  For example, a load balancer can
safely drop a QUIC version 1 Handshake packet with a non-compliant
DCID.  The prohibition against dropping packets with long headers
remains for unknown QUIC versions.
The load balancer MUST NOT make the routing behavior dependent on any
bits in the first octet of the QUIC packet header, except the first
bit, which indicates a long header.  All other bits are QUIC version-
dependent and intermediaries cannot base their design on version-
specific templates.
There are situations where a server pool might be operating two or
more routing algorithms or parameter sets simultaneously.  The load
balancer uses the first two bits of the connection ID to multiplex
incoming DCIDs over these schemes.
This section describes three participants: the configuration agent,
the load balancer, and the server.
The configuration agent selects a length for the server ID encoding.
This length MUST have enough entropy to have a different code point
for each server.  The length MUST be no more than 15 octets to
provide sufficient entropy for server use.
It also assigns a server ID to each server.
When a server needs a new connection ID, it encodes its assigned
server ID in consecutive octets beginning with the second.  All other
bits in the connection ID, except for the first octet, MAY be set to
any other value.  These other bits SHOULD appear random to observers.
The Low-Config CID Algorithm is similar to the plaintext CID
algorithm, but allows the load balancer to assign server IDs
dynamically so that configuration does not require bespoke server ID
assignment.  This also reduces linkability.  However, it requires
state at the load balancer that roughly scales with the number of
connections, until the server ID codespace is exhausted.
The configuration agent selects a length for the server ID encoding
that MUST have at least enough entropy to have a different code point
for each server.  It MUST be no more than seven octets.
The configuration agent also selects an LB Timeout.
The load balancer maintains a table of all assigned server IDs, which
is initialized empty.  On each incoming packet, the load balancer
extracts consecutive octets, beginning with the second octet.  If
these octets match an existing server ID, the packets are routed to
the matching server ID.  As there are no assigned server IDs at
first, the first incoming packet has a non-compliant DCID by
definition.
The server ID table is distinct for each instance of low-config CID
algorithm configuration, even if two configurations use the same
server ID length.  Thus a given server ID might correspond to a
different server in each configuration.
Note that each server will usually have many server IDs assigned to
it.
The load balancer MUST keep track of the most recent observation of
each server ID in the table and delete the entries when the time
since that observation exceeds the LB Timeout.
In QUIC version 1, incoming Connection IDs generated by clients
should be no less than 8 octets, so all non-compliant DCIDs should
not be due to insufficient length.  Load balancers that are operating
the Low-Config CID algorithm SHOULD drop incoming packets with CIDs
too short to execute it unless it can be routed using another
configured algorithm.
If the DCID is non-compliant solely because the server ID is
unassigned, the load balancers follows the procedures in routing-
algorithms and adds the server ID and assignment the table.
Identify the instance of Low-Config CID configuration with the
largest config rotation codepoint.  For example, if configurations
0b10, 0b01, and 0b00 all use the low-config CID algorithm and have
server ID lengths of 3, 5, and 7 octets, respectively, and a
packet comes in with codepoint 0b11, the load balancer would
extract 3 octets for the server ID.
Extract the appropriate number of octets.
If the server ID matches one already in the table, forward the
packet to that server.
If not, the load balancer runs the algorithm of its choosing and
adds the extracted server ID to the table corresponding to the
highest-value Low-Config CID Configuration codepoint.
The server chooses how many octets to reserve for its own use, which
MUST be at least one octet.  It also maintains a list of server IDs
it has observed and the last time it received a packet with that ID.
This list is distinct for each instance of Low-Config CID Algorithm
configuration.
When a server receives a packet, it extracts the server ID.  If the
config rotation bits in the CID encode 4-tuple routing or an
undefined configuration, it uses the highest-value Low-Config CID
config rotation codepoint and extracts the server ID as if that
configuration applied.
If the server ID is not currently in the list, the server adds it.
The server ID's entry is also updated with the most recent arrival of
that server ID.
In QUIC-LB, load balancers do not generate individual connection IDs
for servers.  Instead, they communicate the parameters of an
algorithm to generate routable connection IDs.
This section describes three participants: the configuration agent,
the load balancer, and the server.  For any given QUIC-LB
configuration that enables connection-ID-aware load balancing, there
must be a choice of (1) routing algorithm, (2) server ID allocation
strategy, and (3) algorithm parameters.
Fundamentally, servers generate connection IDs that encode their
server ID.  Load balancers decode the server ID from the CID in
incoming packets to route to the correct server.
There are situations where a server pool might be operating two or
more routing algorithms or parameter sets simultaneously.  The load
balancer uses the first two bits of the connection ID to multiplex
incoming DCIDs over these schemes (see config-rotation).
QUIC-LB servers will generate Connection IDs that are decodable to
extract a server ID in accordance with a specified algorithm and
parameters.  However, QUIC often uses client-generated Connection IDs
prior to receiving a packet from the server.
The config rotation bits (config-rotation) may not correspond to
an active configuration.  Note: a packet with a DCID that
indicates 5-tuple routing (see config-failover) is always
compliant.
The DCID might not be long enough for the decoder to process.
All other DCIDs are compliant.
The routing of long headers with non-compliant DCIDs depends on the
server ID allocation strategy, described in sid-allocation.  However,
the load balancer MUST NOT drop these packets, with one exception.
Load balancers MAY drop packets with long headers and non-compliant
DCIDs if and only if it knows that the encoded QUIC version does not
allow a non- compliant DCID in a packet with that signature.  For
example, a load balancer can safely drop a QUIC version 1 Handshake
packet with a non-compliant DCID, as a version 1 Handshake packet
sent to a QUIC-LB compliant server will always have a server-
generated compliant CID.  The prohibition against dropping packets
with long headers remains for unknown QUIC versions.
Furthermore, while the load balancer function MUST NOT drop packets,
the device might implement other security policies, outside the scope
of this specification, that might force a drop.
There are conditions described below where a load balancer routes a
packet using an "arbitrary algorithm."  It can choose any algorithm,
without coordination with the servers, but the algorithm SHOULD be
deterministic over short time scales so that related packets go to
the same server.  The design of this algorithm SHOULD consider the
version-invariant properties of QUIC described in QUIC-INVARIANTS to
maximize its robustness to future versions of QUIC.
An arbitrary algorithmr MUST NOT make the routing behavior dependent
on any bits in the first octet of the QUIC packet header, except the
first bit, which indicates a long header.  All other bits are QUIC
version-dependent and intermediaries should not base their design on
version-specific templates.
For example, one arbitrary algorithm might convert a non-compliant
DCID to an integer and divided by the number of servers, with the
modulus used to forward the packet.  The number of servers is usually
consistent on the time scale of a QUIC connection handshake.  Another
might simply hash the address/port 4-tuple.  See also version-
invariance.
For any given configuration, the configuration agent must specify if
server IDs will be statically or dynamically allocated.  Load
Balancer configurations with statically allocated server IDs
explicitly include a mapping of server IDs to forwarding addresses.
The corresponding server configurations contain one or more unique
server IDs.
A dynamically allocated configuration does not include any bespoke
assignment, reducing configuration complexity.  However, it places
limits on the maximum server ID length and requires more state at the
load balancer.  In certain edge cases, it can force parts of the
system to fail over to 5-tuple routing for a short time.
In either case, the configuration agent chooses a server ID length
for each configuration that MUST be at least one octet.  For Static
Allocation, the maximum length depends on the algorithm.  For dynamic
allocation, the maximum length is 7 octets.
Conceptually, each configuration has its own set of server ID
allocations, though two static configurations with identical server
ID lengths MAY use a common allocation between them.
A server encodes one of its assigned server IDs in any CID it
generates using the relevant configuration.
In the manual allocation method, the configuration agent assigns at
least one server ID to each server.
When forwarding a packet with a long header and non-compliant DCID,
load balancers MUST forward packets with long headers and non-
compliant DCIDs using an arbitrary algorithm as specified in
arbitrary-algorithm.
In the dynamic allocation method, the load balancer assigns server
IDs dynamically so that configuration does not require bespoke server
ID assignment.  This also reduces linkability.  However, it requires
state at the load balancer that roughly scales with the number of
connections, until the server ID codespace is exhausted.
The configuration agent does not assign server IDs, but does
configure a server ID length and an "LB timeout".  The server ID MUST
be at least one and no more than seven octets.
The load balancer maintains a table of all assigned server IDs and
corresponding routing information, which is initialized empty.  These
tables are independent for each operating configuration.
The load balancer MUST keep track of the most recent observation of
each server ID, in any sort of packet it forwards, in the table and
delete the entries when the time since that observation exceeds the
LB Timeout.
Note that when the load balancer's table for a configuration is
empty, all incoming DCIDs corresponding to that configuration are
non-compliant by definition.
If the config rotation bits do not match a known configuration,
the load balancer routes the packet using an arbitrary algorithm
(see arbitrary-algorithm).
If there is a matching configuration, but the CID is not long
enough to apply the algorithm, the load balancer skips the first
octet of the CID and then reads a server ID from the following
octets, up to the server ID length.  If this server ID matches a
known server ID for that configuration, it forwards the packet
accordingly and takes no further action.  If it does not match, it
routes using an arbitrary algorithm and adds the new server ID to
that server's table entry.
If the sole reason for non-compliance is that the server ID is not
in the load balancer's table, the load balancer routes the packet
with an arbitrary algorithm.  It adds the decoded server ID to
table entry for the server the algorithm chooses and forwards the
packet accordingly.
Each server maintains a list of server IDs assigned to it,
initialized empty.  For each SID, it records the last time it
received any packet with an CID that encoded that SID.
If the config rotation bits do not correspond to a known
configuration, do not attempt to extract a server ID.
If the DCID is not long enough to decode using the configured
algorithm, extract a number of octets equal to the server ID
length, beginning with the second octet.  If the extracted value
does not match a server ID in the server's list, add it to the
list.
If the DCID is long enough to decode but the server ID is not in
the server's list, add it to the list.
After any possible SID is extracted, the server processes the packet
normally.
After loading a new configuration or long periods of idleness, a
server may not have any available SIDs.  This is because an incoming
packet may not the config rotation bits necessary to extract a server
ID in accordance with the algorithm above.  When required to generate
a CID under these conditions, the server MUST generate CIDs using the
5-tuple routing codepoint (see config-failover.  Note that these
connections will not be robust to client address changes while they
use this connection ID.  For this reason, a server SHOULD retire
these connection IDs and replace them with routable ones once it
receives a client-generated CID that allows it to acquire a server
ID.  As, statistically, one in every four such CIDs can provide a
server ID, this is typically a short interval.
For static SID allocation, the server ID length is limited to 16
octets.  There are no parameters specific to this algorithm.
When a server needs a new connection ID, it encodes one of its
assigned server IDs in consecutive octets beginning with the second.
All other bits in the connection ID, except for the first octet, MAY
be set to any other value.  These other bits SHOULD appear random to
observers.
The configuration agent assigns a server ID to every server in its
pool, and determines a server ID length (in octets) sufficiently
large to encode all server IDs, including potential future servers.
The server ID will start in the second octet of the decrypted
connection ID and occupy continuous octets beyond that.
The server ID length MUST be no more than 12 octets, to provide
adequate entropy in the encrypted block.
If server IDs are statically allocated, the server ID length MUST be
no more than 12 octets, to provide servers adequate entropy to
generate unique CIDs.
When generating a routable connection ID, the server MUST choose a
connection ID length between 17 and 20 octets.  The server writes its
provided server ID into the server ID octets and arbitrary bits into
the remaining bits.  These arbitrary bits MAY encode additional
information, and MUST differ between connection IDs.  The encrypted
arbitrary bits MUST be unique for each CID the server generates; the
easiest way to do so is to start the nonce at zero and simply
increment by one for each CID.
Bits in the eighteenth, nineteenth, and twentieth octets SHOULD
appear essentially random to observers.  The first octet is reserved
as described in first-octet.
When generating a routable connection ID, the server MUST choose a
connection ID length between 17 and 20 octets.  The server writes its
server ID into the server ID octets and arbitrary bits into the
remaining bits.  These arbitrary bits MAY encode additional
information, and MUST differ between connection IDs.  Bits in the
eighteenth, nineteenth, and twentieth octets SHOULD appear
essentially random to observers.  The first octet is reserved as
described in first-octet.
The load balancer and server MUST agree on a routing algorithm and
the relevant parameters for that algorithm.
Except for the Low-config CID algorithm, each server MUST know its
server ID for each configuration, and the load balancer MUST have
forwarding instructions for each server ID.
For all algorithms, the load balancer and servers MUST have a common
understanding of the server ID length.
For Low-Config CID Routing, the servers and load balancer also MUST
have a common understanding of the LB timeout.
The load balancer and server MUST agree on a routing algorithm,
server ID allocation method, and the relevant parameters for that
algorithm.
All algorithms require a server ID length.  If server IDs are
statically allocated, the load balancer MUST receive the full table
of mappings, and each server must receive its assigned SID(s), from
the configuration agent.