00001 /** @file 00002 00003 HTTP configuration support. 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 */ 00023 00024 #ifndef _I_REC_HTTP_H 00025 #define _I_REC_HTTP_H 00026 00027 #include <ts/ink_inet.h> 00028 #include <ts/ink_resolver.h> 00029 #include <ts/apidefs.h> 00030 #include <ts/Vec.h> 00031 #include <ts/apidefs.h> 00032 00033 /// Load default inbound IP addresses from the configuration file. 00034 void RecHttpLoadIp( 00035 char const* name, ///< Name of value in configuration file. 00036 IpAddr& ip4, ///< [out] IPv4 address. 00037 IpAddr& ip6 ///< [out] Ipv6 address. 00038 ); 00039 00040 /** A set of session protocols. 00041 This depends on using @c SessionProtocolNameRegistry to get the indices. 00042 */ 00043 class SessionProtocolSet { 00044 typedef SessionProtocolSet self; ///< Self reference type. 00045 /// Storage for the set - a bit vector. 00046 uint32_t m_bits; 00047 public: 00048 // The right way. 00049 // static int const MAX = sizeof(m_bits) * CHAR_BIT; 00050 // The RHEL5/gcc 4.1.2 way 00051 static int const MAX = sizeof(uint32_t) * 8; 00052 /// Default constructor. 00053 /// Constructs and empty set. 00054 SessionProtocolSet() : m_bits(0) { } 00055 00056 uint32_t indexToMask(int idx) const { 00057 return 0 <= idx && idx < static_cast<int>(MAX) 00058 ? static_cast<uint32_t>(1) << idx 00059 : 0 00060 ; 00061 } 00062 00063 /// Mark the protocol at @a idx as present. 00064 void markIn(int idx) { m_bits |= this->indexToMask(idx); } 00065 /// Mark all the protocols in @a that as present in @a this. 00066 void markIn(self const& that) { m_bits |= that.m_bits; } 00067 /// Mark the protocol at a idx as not present. 00068 void markOut(int idx) { m_bits &= ~this->indexToMask(idx); } 00069 /// Mark the protocols in @a that as not in @a this. 00070 void markOut(self const& that) { m_bits &= ~(that.m_bits); } 00071 /// Test if a protocol is in the set. 00072 bool contains(int idx) const { return 0 != (m_bits & this->indexToMask(idx)); } 00073 /// Test if all the protocols in @a that are in @a this protocol set. 00074 bool contains(self const& that) const { return that.m_bits == (that.m_bits & m_bits); } 00075 /// Mark all possible protocols. 00076 void markAllIn() { m_bits = ~static_cast<uint32_t>(0); } 00077 /// Clear all protocols. 00078 void markAllOut() { m_bits = 0; } 00079 00080 /// Check for intersection. 00081 bool intersects(self const& that) { return 0 != (m_bits & that.m_bits); } 00082 00083 /// Check for empty set. 00084 bool isEmpty() const { return m_bits == 0; } 00085 00086 /// Equality (identical sets). 00087 bool operator == (self const& that) const { return m_bits == that.m_bits; } 00088 }; 00089 00090 // Predefined sets of protocols, useful for configuration. 00091 extern SessionProtocolSet HTTP_PROTOCOL_SET; 00092 extern SessionProtocolSet HTTP2_PROTOCOL_SET; 00093 extern SessionProtocolSet SPDY_PROTOCOL_SET; 00094 extern SessionProtocolSet DEFAULT_NON_TLS_SESSION_PROTOCOL_SET; 00095 extern SessionProtocolSet DEFAULT_TLS_SESSION_PROTOCOL_SET; 00096 00097 /** Registered session protocol names. 00098 00099 We do this to avoid lots of string compares. By normalizing the 00100 string names we can just compare their indices in this table. 00101 00102 @internal To simplify the implementation we limit the maximum 00103 number of strings to 32. That will be sufficient for the forseeable 00104 future. We can come back to this if it ever becomes a problem. 00105 00106 @internal Because we have so few strings we just use a linear search. 00107 If the size gets much larger we should consider doing something more 00108 clever. 00109 */ 00110 class SessionProtocolNameRegistry { 00111 public: 00112 static int const MAX = SessionProtocolSet::MAX; ///< Maximum # of registered names. 00113 static int const INVALID = -1; ///< Normalized invalid index value. 00114 00115 /// Default constructor. 00116 /// Creates empty registry with no names. 00117 SessionProtocolNameRegistry(); 00118 00119 /// Destructor. 00120 /// Cleans up strings. 00121 ~SessionProtocolNameRegistry(); 00122 00123 /** Get the index for @a name, registering it if needed. 00124 The name is copied internally. 00125 @return The index for the registered @a name. 00126 */ 00127 int toIndex(char const* name); 00128 00129 /** Get the index for @a name, registering it if needed. 00130 The caller @b guarantees @a name is persistent and immutable. 00131 @return The index for the registered @a name. 00132 */ 00133 int toIndexConst(char const* name); 00134 00135 /** Convert a @a name to an index. 00136 @return The index for @a name or @c INVALID if it is not registered. 00137 */ 00138 int indexFor(char const* name) const; 00139 00140 /** Convert an @a index to the corresponding name. 00141 @return A pointer to the name or @c NULL if the index isn't registered. 00142 */ 00143 char const* nameFor(int index) const; 00144 00145 /// Mark protocols as present in @a sp_set based on the names in @a value. 00146 /// The names can be separated by ;/|,: and space. 00147 /// @internal This is separated out to make it easy to access from the plugin API 00148 /// implementation. 00149 void markIn(char const* value, SessionProtocolSet& sp_set); 00150 00151 protected: 00152 unsigned int m_n; ///< Index of first unused slot. 00153 char const* m_names[MAX]; ///< Pointers to registered names. 00154 uint8_t m_flags[MAX]; ///< Flags for each name. 00155 00156 static uint8_t const F_ALLOCATED = 0x1; ///< Flag for allocated by this instance. 00157 }; 00158 00159 extern SessionProtocolNameRegistry globalSessionProtocolNameRegistry; 00160 00161 /** Description of an proxy port. 00162 00163 This consolidates the options needed for proxy ports, both data 00164 and parsing. It provides a static global set of ports for 00165 convenience although it can be used with an externally provided 00166 set. 00167 00168 Options are described by a colon separated list of keywords 00169 without spaces. The options are applied in left to right order. If 00170 options do not conflict the order is irrelevant. 00171 00172 IPv6 addresses must be enclosed by brackets. Unfortunate but colon is 00173 so overloaded there's no other option. 00174 */ 00175 struct HttpProxyPort { 00176 private: 00177 typedef HttpProxyPort self; ///< Self reference type. 00178 public: 00179 /// Explicitly supported collection of proxy ports. 00180 typedef Vec<self> Group; 00181 00182 /// Type of transport on the connection. 00183 enum TransportType { 00184 TRANSPORT_DEFAULT = 0, ///< Default (normal HTTP). 00185 TRANSPORT_COMPRESSED, ///< Compressed HTTP. 00186 TRANSPORT_BLIND_TUNNEL, ///< Blind tunnel (no processing). 00187 TRANSPORT_SSL, ///< SSL connection. 00188 TRANSPORT_PLUGIN /// < Protocol plugin connection 00189 }; 00190 00191 int m_fd; ///< Pre-opened file descriptor if present. 00192 TransportType m_type; ///< Type of connection. 00193 in_port_t m_port; ///< Port on which to listen. 00194 uint8_t m_family; ///< IP address family. 00195 /// True if inbound connects (from client) are transparent. 00196 bool m_inbound_transparent_p; 00197 /// True if outbound connections (to origin servers) are transparent. 00198 bool m_outbound_transparent_p; 00199 // True if transparent pass-through is enabled on this port. 00200 bool m_transparent_passthrough; 00201 /// Local address for inbound connections (listen address). 00202 IpAddr m_inbound_ip; 00203 /// Local address for outbound connections (to origin server). 00204 IpAddr m_outbound_ip4; 00205 /// Local address for outbound connections (to origin server). 00206 IpAddr m_outbound_ip6; 00207 /// Ordered preference for DNS resolution family ( @c FamilyPrefence ) 00208 /// A value of @c PREFER_NONE indicates that entry and subsequent ones 00209 /// are invalid. 00210 HostResPreferenceOrder m_host_res_preference; 00211 /// Static preference list that is the default value. 00212 static HostResPreferenceOrder const DEFAULT_HOST_RES_PREFERENCE; 00213 /// Enabled session transports for this port. 00214 SessionProtocolSet m_session_protocol_preference; 00215 00216 /// Default constructor. 00217 HttpProxyPort(); 00218 00219 /** Select the local outbound address object. 00220 00221 @return The IP address for @a family 00222 */ 00223 IpAddr& outboundIp( 00224 uint16_t family ///< IP address family. 00225 ); 00226 00227 /// Check for SSL port. 00228 bool isSSL() const; 00229 00230 /// Check for SSL port. 00231 bool isPlugin() const; 00232 00233 /// Process options text. 00234 /// @a opts should not contain any whitespace, only the option string. 00235 /// This object's internal state is updated as specified by @a opts. 00236 /// @return @c true if a port option was successfully processed, @c false otherwise. 00237 bool processOptions( 00238 char const* opts ///< String containing the options. 00239 ); 00240 00241 /** Global instance. 00242 00243 This is provided because most of the work with this data is used as a singleton 00244 and it's handy to encapsulate it here. 00245 */ 00246 static Vec<self>& global(); 00247 00248 /// Check for SSL ports. 00249 /// @return @c true if any port in @a ports is an SSL port. 00250 static bool hasSSL( 00251 Group const& ports ///< Ports to check. 00252 ); 00253 00254 /// Check for SSL ports. 00255 /// @return @c true if any global port is an SSL port. 00256 static bool hasSSL(); 00257 00258 /** Load all relevant configuration data. 00259 00260 This is hardwired to look up the appropriate values in the 00261 configuration files. It clears @a ports and then loads all found 00262 values in to it. 00263 00264 @return @c true if at least one valid port description was 00265 found, @c false if none. 00266 */ 00267 static bool loadConfig( 00268 Vec<self>& ports ///< Destination for found port data. 00269 ); 00270 00271 /** Load all relevant configuration data into the global ports. 00272 00273 @return @c true if at least one valid port description was 00274 found, @c false if none. 00275 */ 00276 static bool loadConfig(); 00277 00278 /** Load ports from a value string. 00279 00280 Load ports from single string with port descriptors. Ports 00281 found are added to @a ports. @a value may safely be @c NULL or empty. 00282 00283 @note This is used primarily internally but is available if needed. 00284 @return @c true if a valid port was found, @c false if none. 00285 */ 00286 static bool loadValue( 00287 Vec<self>& ports, ///< Destination for found port data. 00288 char const* value ///< Source port data. 00289 ); 00290 00291 /** Load ports from a value string into the global ports. 00292 00293 Load ports from single string of port descriptors into the 00294 global set of ports. @a value may safely be @c NULL or empty. 00295 00296 @return @c true if a valid port was found, @c false if none. 00297 */ 00298 static bool loadValue( 00299 char const* value ///< Source port data. 00300 ); 00301 00302 /// Load default value if @a ports is empty. 00303 /// @return @c true if the default was needed / loaded. 00304 static bool loadDefaultIfEmpty( 00305 Vec<self>& ports ///< Load target. 00306 ); 00307 00308 /// Load default value into the global set if it is empty. 00309 /// @return @c true if the default was needed / loaded. 00310 static bool loadDefaultIfEmpty(); 00311 00312 /** Find an HTTP port in @a ports. 00313 If @a family is specified then only ports for that family 00314 are checked. 00315 @return The port if found, @c NULL if not. 00316 */ 00317 static self* findHttp( 00318 Group const& ports, ///< Group to search. 00319 uint16_t family = AF_UNSPEC ///< Desired address family. 00320 ); 00321 00322 /** Find an HTTP port in the global ports. 00323 If @a family is specified then only ports for that family 00324 are checked. 00325 @return The port if found, @c NULL if not. 00326 */ 00327 static self* findHttp(uint16_t family = AF_UNSPEC); 00328 00329 /** Create text description to be used for inter-process access. 00330 Prints the file descriptor and then any options. 00331 00332 @return The number of characters used for the description. 00333 */ 00334 int print( 00335 char* out, ///< Output string. 00336 size_t n ///< Maximum output length. 00337 ); 00338 00339 static char const* const PORTS_CONFIG_NAME; ///< New unified port descriptor. 00340 00341 /// Default value if no other values can be found. 00342 static char const* const DEFAULT_VALUE; 00343 00344 // Keywords (lower case versions, but compares should be case insensitive) 00345 static char const* const OPT_FD_PREFIX; ///< Prefix for file descriptor value. 00346 static char const* const OPT_OUTBOUND_IP_PREFIX; ///< Prefix for inbound IP address. 00347 static char const* const OPT_INBOUND_IP_PREFIX; ///< Prefix for outbound IP address. 00348 static char const* const OPT_IPV6; ///< IPv6. 00349 static char const* const OPT_IPV4; ///< IPv4 00350 static char const* const OPT_TRANSPARENT_INBOUND; ///< Inbound transparent. 00351 static char const* const OPT_TRANSPARENT_OUTBOUND; ///< Outbound transparent. 00352 static char const* const OPT_TRANSPARENT_FULL; ///< Full transparency. 00353 static char const* const OPT_TRANSPARENT_PASSTHROUGH; ///< Pass-through non-HTTP. 00354 static char const* const OPT_SSL; ///< SSL (experimental) 00355 static char const* const OPT_PLUGIN; ///< Protocol Plugin handle (experimental) 00356 static char const* const OPT_BLIND_TUNNEL; ///< Blind tunnel. 00357 static char const* const OPT_COMPRESSED; ///< Compressed. 00358 static char const* const OPT_HOST_RES_PREFIX; ///< Set DNS family preference. 00359 static char const* const OPT_PROTO_PREFIX; ///< Transport layer protocols. 00360 00361 static Vec<self>& m_global; ///< Global ("default") data. 00362 00363 protected: 00364 /// Process @a value for DNS resolution family preferences. 00365 void processFamilyPreference(char const* value); 00366 /// Process @a value for session protocol preferences. 00367 void processSessionProtocolPreference(char const* value); 00368 00369 /** Check a prefix option and find the value. 00370 @return The address of the start of the value, or @c NULL if the prefix doesn't match. 00371 */ 00372 00373 char const* checkPrefix( char const* src ///< Input text 00374 , char const* prefix ///< Keyword prefix 00375 , size_t prefix_len ///< Length of keyword prefix. 00376 ); 00377 }; 00378 00379 inline bool HttpProxyPort::isSSL() const { return TRANSPORT_SSL == m_type; } 00380 inline bool HttpProxyPort::isPlugin() const { return TRANSPORT_PLUGIN == m_type; } 00381 00382 inline IpAddr& 00383 HttpProxyPort::outboundIp(uint16_t family) { 00384 static IpAddr invalid; // dummy to make compiler happy about return. 00385 if (AF_INET == family) return m_outbound_ip4; 00386 else if (AF_INET6 == family) return m_outbound_ip6; 00387 ink_release_assert(!"Invalid family for outbound address on proxy port."); 00388 return invalid; // never happens but compiler insists. 00389 } 00390 00391 inline bool 00392 HttpProxyPort::loadValue(char const* value) { 00393 return self::loadValue(m_global, value); 00394 } 00395 inline bool 00396 HttpProxyPort::loadConfig() { 00397 return self::loadConfig(m_global); 00398 } 00399 inline bool 00400 HttpProxyPort::loadDefaultIfEmpty() { 00401 return self::loadDefaultIfEmpty(m_global); 00402 } 00403 inline Vec<HttpProxyPort>& 00404 HttpProxyPort::global() { 00405 return m_global; 00406 } 00407 inline bool 00408 HttpProxyPort::hasSSL() { 00409 return self::hasSSL(m_global); 00410 } 00411 inline HttpProxyPort* HttpProxyPort::findHttp(uint16_t family) { 00412 return self::findHttp(m_global, family); 00413 } 00414 00415 /** Session Protocol initialization. 00416 This must be called before any proxy port parsing is done. 00417 */ 00418 extern void ts_session_protocol_well_known_name_indices_init(); 00419 00420 #endif // I_REC_HTTP_H