LCOV - code coverage report
Current view: top level - source/common/network - cidr_range.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 1 6 16.7 %
Date: 2024-01-05 06:35:25 Functions: 1 6 16.7 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstddef>
       4             : #include <string>
       5             : #include <vector>
       6             : 
       7             : #include "envoy/config/core/v3/address.pb.h"
       8             : #include "envoy/network/address.h"
       9             : 
      10             : #include "source/common/protobuf/protobuf.h"
      11             : 
      12             : #include "xds/core/v3/cidr.pb.h"
      13             : 
      14             : namespace Envoy {
      15             : namespace Network {
      16             : namespace Address {
      17             : 
      18             : /**
      19             :  * A "Classless Inter-Domain Routing" range of internet addresses, aka a CIDR range, consisting
      20             :  * of an Ip address and a count of leading bits included in the mask. Other than those leading
      21             :  * bits, all of the other bits of the Ip address are zero. For more info, see RFC1519 or
      22             :  * https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing.
      23             :  */
      24             : class CidrRange {
      25             : public:
      26             :   /**
      27             :    * Constructs an uninitialized range: length == -1, and there is no associated address.
      28             :    */
      29             :   CidrRange();
      30             : 
      31           0 :   CidrRange(const CidrRange& other) = default;
      32        1269 :   CidrRange(CidrRange&& other) = default;
      33             : 
      34             :   /**
      35             :    * Overwrites this with other.
      36             :    */
      37             :   CidrRange& operator=(const CidrRange& other);
      38             : 
      39             :   /**
      40             :    * @return true if the ranges are identical.
      41             :    */
      42             :   bool operator==(const CidrRange& other) const;
      43             : 
      44             :   /**
      45             :    * @return Ip address data IFF length >= 0, otherwise nullptr.
      46             :    */
      47             :   const Ip* ip() const;
      48             : 
      49             :   /**
      50             :    * TODO(jamessynge) Consider making this absl::optional<int> length, or modifying the create()
      51             :    * methods below to return absl::optional<CidrRange> (the latter is probably better).
      52             :    * @return the number of bits of the address that are included in the mask. -1 if uninitialized
      53             :    *         or invalid, else in the range 0 to 32 for IPv4, and 0 to 128 for IPv6.
      54             :    */
      55             :   int length() const;
      56             : 
      57             :   /**
      58             :    * @return true if the address argument is in the range of this object, false if not, including
      59             :              if the range is uninitialized or if the argument is not of the same IpVersion.
      60             :    */
      61             :   bool isInRange(const Instance& address) const;
      62             : 
      63             :   /**
      64             :    * @return a human readable string for the range. This string will be in the following format:
      65             :    *         - For IPv4 ranges: "1.2.3.4/32" or "10.240.0.0/16"
      66             :    *         - For IPv6 ranges: "1234:5678::f/128" or "1234:5678::/64"
      67             :    */
      68             :   std::string asString() const;
      69             : 
      70             :   /**
      71             :    * @return true if this instance is valid; address != nullptr && length is appropriate for the
      72             :    *         IP version (these are checked during construction, and reduced down to a check of
      73             :    *         the length).
      74             :    */
      75           0 :   bool isValid() const { return length_ >= 0; }
      76             : 
      77             :   /**
      78             :    * TODO(ccaraman): Update CidrRange::create to support only constructing valid ranges.
      79             :    * @return a CidrRange instance with the specified address and length, modified so that the only
      80             :    *         bits that might be non-zero are in the high-order length bits, and so that length is
      81             :    *         in the appropriate range (0 to 32 for IPv4, 0 to 128 for IPv6). If the address or
      82             :    *         length is invalid, then the range will be invalid (i.e. length == -1).
      83             :    */
      84             :   static CidrRange create(InstanceConstSharedPtr address, int length);
      85             :   static CidrRange create(const std::string& address, int length);
      86             : 
      87             :   /**
      88             :    * Constructs an CidrRange from a string with this format (same as returned
      89             :    * by CidrRange::asString above):
      90             :    *      <address>/<length>    e.g. "10.240.0.0/16" or "1234:5678::/64"
      91             :    * TODO(ccaraman): Update CidrRange::create to support only constructing valid ranges.
      92             :    * @return a CidrRange instance with the specified address and length if parsed successfully,
      93             :    *         else with no address and a length of -1.
      94             :    */
      95             :   static CidrRange create(const std::string& range);
      96             : 
      97             :   /**
      98             :    * Constructs a CidrRange from envoy::config::core::v3::CidrRange.
      99             :    * TODO(ccaraman): Update CidrRange::create to support only constructing valid ranges.
     100             :    */
     101             :   static CidrRange create(const envoy::config::core::v3::CidrRange& cidr);
     102             : 
     103             :   /**
     104             :    * Constructs a CidrRange from xds::core::v3::CidrRange.
     105             :    * TODO(ccaraman): Update CidrRange::create to support only constructing valid ranges.
     106             :    */
     107             :   static CidrRange create(const xds::core::v3::CidrRange& cidr);
     108             : 
     109             :   /**
     110             :    * Given an IP address and a length of high order bits to keep, returns an address
     111             :    * where those high order bits are unmodified, and the remaining bits are all zero.
     112             :    * length_io is reduced to be at most 32 for IPv4 address and at most 128 for IPv6
     113             :    * addresses. If the address is invalid or the length is less than zero, then *length_io
     114             :    * is set to -1 and nullptr is returned.
     115             :    * @return a pointer to an address where the high order *length_io bits are unmodified
     116             :    *         from address, and *length_io is in the range 0 to N, where N is the number of bits
     117             :    *         in an address of the IP version (i.e. address->ip()->version()).
     118             :    */
     119             :   static InstanceConstSharedPtr truncateIpAddressAndLength(InstanceConstSharedPtr address,
     120             :                                                            int* length_io);
     121             : 
     122             : private:
     123             :   CidrRange(InstanceConstSharedPtr address, int length);
     124             : 
     125             :   InstanceConstSharedPtr address_;
     126             :   int length_;
     127             : };
     128             : 
     129             : /**
     130             :  * Class for keeping a list of CidrRanges, and then determining whether an
     131             :  * IP address is in the CidrRange list.
     132             :  */
     133             : class IpList {
     134             : public:
     135             :   static absl::StatusOr<std::unique_ptr<IpList>>
     136             :   create(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs);
     137             : 
     138           0 :   IpList() = default;
     139             : 
     140             :   bool contains(const Instance& address) const;
     141           0 :   size_t getIpListSize() const { return ip_list_.size(); };
     142           0 :   const std::string& error() const { return error_; }
     143             : 
     144             : private:
     145             :   explicit IpList(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs);
     146             :   std::vector<CidrRange> ip_list_;
     147             :   std::string error_;
     148             : };
     149             : 
     150             : } // namespace Address
     151             : } // namespace Network
     152             : } // namespace Envoy

Generated by: LCOV version 1.15