Line data Source code
1 : #pragma once
2 :
3 : #include <map>
4 : #include <memory>
5 : #include <string>
6 : #include <tuple>
7 : #include <vector>
8 :
9 : #include "envoy/common/optref.h"
10 : #include "envoy/common/time.h"
11 : #include "envoy/config/core/v3/protocol.pb.h"
12 : #include "envoy/event/dispatcher.h"
13 :
14 : #include "absl/strings/string_view.h"
15 :
16 : namespace Envoy {
17 : namespace Http {
18 :
19 : /**
20 : * Tracks information used to make an HTTP connection to an origin server.
21 : *
22 : * This includes Alternate protocols, SRTT, Quic brokenness, etc.
23 : *
24 : * See https://tools.ietf.org/html/rfc7838 for HTTP Alternative Services and
25 : * https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-04 for the
26 : * "HTTPS" DNS resource record.
27 : */
28 : class HttpServerPropertiesCache {
29 : public:
30 : /**
31 : * Represents an HTTP origin to be connected too.
32 : */
33 : struct Origin {
34 : public:
35 0 : Origin() = default;
36 0 : Origin(const Origin& other) = default;
37 : Origin(absl::string_view scheme, absl::string_view hostname, uint32_t port)
38 0 : : scheme_(scheme), hostname_(hostname), port_(port) {}
39 0 : Origin& operator=(const Origin&) = default;
40 :
41 0 : bool operator==(const Origin& other) const {
42 0 : return std::tie(scheme_, hostname_, port_) ==
43 0 : std::tie(other.scheme_, other.hostname_, other.port_);
44 0 : }
45 :
46 0 : bool operator!=(const Origin& other) const { return !this->operator==(other); }
47 :
48 0 : bool operator<(const Origin& other) const {
49 0 : return std::tie(scheme_, hostname_, port_) <
50 0 : std::tie(other.scheme_, other.hostname_, other.port_);
51 0 : }
52 :
53 0 : bool operator>(const Origin& other) const {
54 0 : return std::tie(scheme_, hostname_, port_) >
55 0 : std::tie(other.scheme_, other.hostname_, other.port_);
56 0 : }
57 :
58 0 : bool operator<=(const Origin& other) const {
59 0 : return std::tie(scheme_, hostname_, port_) <=
60 0 : std::tie(other.scheme_, other.hostname_, other.port_);
61 0 : }
62 :
63 0 : bool operator>=(const Origin& other) const {
64 0 : return std::tie(scheme_, hostname_, port_) >=
65 0 : std::tie(other.scheme_, other.hostname_, other.port_);
66 0 : }
67 :
68 : std::string scheme_;
69 : std::string hostname_;
70 : uint32_t port_{};
71 : };
72 :
73 : /**
74 : * Represents an alternative protocol that can be used to connect to an origin
75 : * with a specified expiration time.
76 : */
77 : struct AlternateProtocol {
78 : public:
79 : AlternateProtocol(absl::string_view alpn, absl::string_view hostname, uint32_t port,
80 : MonotonicTime expiration)
81 0 : : alpn_(alpn), hostname_(hostname), port_(port), expiration_(expiration) {}
82 :
83 0 : bool operator==(const AlternateProtocol& other) const {
84 0 : return std::tie(alpn_, hostname_, port_, expiration_) ==
85 0 : std::tie(other.alpn_, other.hostname_, other.port_, other.expiration_);
86 0 : }
87 :
88 0 : bool operator!=(const AlternateProtocol& other) const { return !this->operator==(other); }
89 :
90 : std::string alpn_;
91 : std::string hostname_;
92 : uint32_t port_;
93 : MonotonicTime expiration_;
94 : };
95 :
96 : class Http3StatusTracker {
97 : public:
98 0 : virtual ~Http3StatusTracker() = default;
99 :
100 : // Returns true if HTTP/3 is broken.
101 : virtual bool isHttp3Broken() const PURE;
102 : // Returns true if HTTP/3 is confirmed to be working.
103 : virtual bool isHttp3Confirmed() const PURE;
104 : // Returns true if HTTP/3 has failed recently.
105 : virtual bool hasHttp3FailedRecently() const PURE;
106 : // Marks HTTP/3 broken for a period of time, subject to backoff.
107 : virtual void markHttp3Broken() PURE;
108 : // Marks HTTP/3 as confirmed to be working and resets the backoff timeout.
109 : virtual void markHttp3Confirmed() PURE;
110 : // Marks HTTP/3 as failed recently.
111 : virtual void markHttp3FailedRecently() PURE;
112 : };
113 :
114 48 : virtual ~HttpServerPropertiesCache() = default;
115 :
116 : /**
117 : * Sets the possible alternative protocols which can be used to connect to the
118 : * specified origin. Expires after the specified expiration time.
119 : * @param origin The origin to set alternate protocols for.
120 : * @param protocols A list of alternate protocols. This list may be truncated
121 : * by the cache.
122 : */
123 : virtual void setAlternatives(const Origin& origin,
124 : std::vector<AlternateProtocol>& protocols) PURE;
125 :
126 : /**
127 : * Sets the srtt estimate for an origin.
128 : * @param origin The origin to set network characteristics for.
129 : * @param srtt The smothed round trip time for the origin.
130 : */
131 : virtual void setSrtt(const Origin& origin, std::chrono::microseconds srtt) PURE;
132 :
133 : /**
134 : * Returns the srtt estimate for an origin, or zero, if no srtt is cached.
135 : * @param origin The origin to get network characteristics for.
136 : */
137 : virtual std::chrono::microseconds getSrtt(const Origin& origin) const PURE;
138 :
139 : /**
140 : * Sets the number of concurrent streams allowed by the last connection to this origin.
141 : * @param origin The origin to set network characteristics for.
142 : * @param srtt The number of concurrent streams allowed.
143 : */
144 : virtual void setConcurrentStreams(const Origin& origin, uint32_t concurrent_streams) PURE;
145 :
146 : /**
147 : * Returns the number of concurrent streams allowed by the last connection to this origin,
148 : * or zero if no limit was set.
149 : * Note that different servers serving a given origin may have different
150 : * characteristics, so this is a best guess estimate not a guarantee.
151 : * @param origin The origin to get network characteristics for.
152 : */
153 : virtual uint32_t getConcurrentStreams(const Origin& origin) const PURE;
154 :
155 : /**
156 : * Returns the possible alternative protocols which can be used to connect to the
157 : * specified origin, or nullptr if not alternatives are found. The returned reference
158 : * is owned by the HttpServerPropertiesCache and is valid until the next operation on the
159 : * HttpServerPropertiesCache.
160 : * @param origin The origin to find alternate protocols for.
161 : * @return An optional list of alternate protocols for the given origin.
162 : */
163 : virtual OptRef<const std::vector<AlternateProtocol>> findAlternatives(const Origin& origin) PURE;
164 :
165 : /**
166 : * Returns the number of entries in the map.
167 : * @return the number if entries in the map.
168 : */
169 : virtual size_t size() const PURE;
170 :
171 : /**
172 : * @param origin The origin to get HTTP/3 status tracker for.
173 : * @return the existing status tracker or creating a new one if there is none.
174 : */
175 : virtual HttpServerPropertiesCache::Http3StatusTracker&
176 : getOrCreateHttp3StatusTracker(const Origin& origin) PURE;
177 : };
178 :
179 : using HttpServerPropertiesCacheSharedPtr = std::shared_ptr<HttpServerPropertiesCache>;
180 : using Http3StatusTrackerPtr = std::unique_ptr<HttpServerPropertiesCache::Http3StatusTracker>;
181 :
182 : /**
183 : * A manager for multiple alternate protocols caches.
184 : */
185 : class HttpServerPropertiesCacheManager {
186 : public:
187 131 : virtual ~HttpServerPropertiesCacheManager() = default;
188 :
189 : /**
190 : * Get an alternate protocols cache.
191 : * @param config supplies the cache parameters. If a cache exists with the same parameters it
192 : * will be returned, otherwise a new one will be created.
193 : * @param dispatcher supplies the current thread's dispatcher, for cache creation.
194 : */
195 : virtual HttpServerPropertiesCacheSharedPtr
196 : getCache(const envoy::config::core::v3::AlternateProtocolsCacheOptions& config,
197 : Event::Dispatcher& dispatcher) PURE;
198 : };
199 :
200 : using HttpServerPropertiesCacheManagerSharedPtr = std::shared_ptr<HttpServerPropertiesCacheManager>;
201 :
202 : /**
203 : * Factory for getting an alternate protocols cache manager.
204 : */
205 : class HttpServerPropertiesCacheManagerFactory {
206 : public:
207 131 : virtual ~HttpServerPropertiesCacheManagerFactory() = default;
208 :
209 : /**
210 : * Get the alternate protocols cache manager.
211 : */
212 : virtual HttpServerPropertiesCacheManagerSharedPtr get() PURE;
213 : };
214 :
215 : } // namespace Http
216 : } // namespace Envoy
|