1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8 
9 #pragma once
10 
11 #include <folly/Expected.h>
12 #include <quic/QuicException.h>
13 #include <quic/codec/ConnectionIdAlgo.h>
14 #include <quic/codec/QuicConnectionId.h>
15 
16 namespace quic {
17 
18 /**
19  * Default implementation with algorithms to encode and decode for
20  * ConnectionId given routing info (embedded in ServerConnectionIdParams)
21  *
22  * The schema for connection id is defined as follows:
23  *
24  * First 2 (0 - 1) bits are reserved for short version id of the connection id
25  * If the load balancer (e.g. L4 lb) doesn't understand this version,
26  * it can fallback to default routing
27  * Depending on version following mappings:
28  * Version 1:
29  *    Next 16 bits (2 - 17)  are reserved for host id (L4 LB use)
30  *    Next 8 bits (18 - 25) are reserved for worker id
31  *    Next bit 26 is reserved for the Quic server id: server id is used to
32  *    distinguish between the takeover instance and the taken over one
33    0     1   2 3 4 .. 17    18 .. 25        26        27 28 .. 63
34   |VERSION|  For L4 LB    | WORKER_ID  | SERVER_ID |  ..
35  *
36  * Version 2:
37  *    Next 6 bits (2 - 7) are not used (random)
38  *    Next 24 bits (8 - 31) are reserved for host id
39  *    Next 8 bits (32 - 39) are reserved for worker id
40  *    Next bit 40 is reserved for the Quic server id
41    0     1 2  ..  7 8   ..   31 32   ..   39    40       41 ... 63
42   |VERSION| UNUSED | For L4 LB | WORKER_ID  | SERVER_ID |  ..
43 
44  */
45 class DefaultConnectionIdAlgo : public ConnectionIdAlgo {
46  public:
47   ~DefaultConnectionIdAlgo() override = default;
48 
49   /**
50    * Check if this implementation of algorithm can parse the given ConnectionId
51    */
52   bool canParse(const ConnectionId& id) const noexcept override;
53 
54   /**
55    * Parses ServerConnectionIdParams from the given connection id.
56    */
57   folly::Expected<ServerConnectionIdParams, QuicInternalException>
58   parseConnectionId(const ConnectionId& id) noexcept override;
59 
60   /**
61    * Encodes the given ServerConnectionIdParams into connection id
62    */
63   folly::Expected<ConnectionId, QuicInternalException> encodeConnectionId(
64       const ServerConnectionIdParams& params) noexcept override;
65 };
66 
67 /**
68  * Factory Interface to create ConnectionIdAlgo instance.
69  */
70 class DefaultConnectionIdAlgoFactory : public ConnectionIdAlgoFactory {
71  public:
72   ~DefaultConnectionIdAlgoFactory() override = default;
73 
make()74   std::unique_ptr<ConnectionIdAlgo> make() override {
75     return std::make_unique<DefaultConnectionIdAlgo>();
76   }
77 };
78 
79 } // namespace quic
80