blob: db04375aa42acb9f25609a577a2b81d9076181f1 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_NETWORK_LIB_NET_INTERFACES_CPP_NET_INTERFACES_H_
#define SRC_CONNECTIVITY_NETWORK_LIB_NET_INTERFACES_CPP_NET_INTERFACES_H_
#include <fuchsia/net/interfaces/cpp/fidl.h>
#include <optional>
#include <string>
#include <unordered_map>
#include <variant>
namespace net::interfaces {
// Move-only wrapper for fuchsia::net::interface::Properties that guarantees
// that its inner |properties_| are valid and complete properties as reported by
// |VerifyCompleteProperties|.
class Properties final {
public:
// Creates an |Properties| if |properties| are valid complete
// properties as reported by |VerifyCompleteProperties|.
static std::optional<Properties> VerifyAndCreate(fuchsia::net::interfaces::Properties properties);
Properties(Properties&& interface) noexcept;
Properties& operator=(Properties&& interface) noexcept;
~Properties();
bool operator==(const Properties& rhs) const;
// Updates this instance with the values set in |properties|. Fields not set in |properties|
// retain their previous values. Returns false if the |properties| has a missing or mismatched
// |id| field, or if any field set in |properties| has an invalid value (e.g. an address that does
// not actually contain an address).
//
// |properties| will be modified such that it contains the previous values of all mutable fields
// which changed upon return. This is useful when a user needs to know precisely how the addresses
// field has changed as a result of the update. Note that in particular, the |id| field is
// immutable and thus will not be present in |properties| upon return.
bool Update(fuchsia::net::interfaces::Properties* properties);
// Returns true iff the interface's properties indicate that it is globally routable.
// This is defined as being an interface that is not loopback, is online, and either has an IPv4
// address and a default IPv4 route or has a global unicast IPv6 address and a default IPv6 route.
bool IsGloballyRoutable() const;
uint64_t id() const { return properties_.id(); }
const ::std::string& name() const { return properties_.name(); }
const fuchsia::net::interfaces::DeviceClass& device_class() const {
return properties_.device_class();
}
bool is_loopback() const;
bool online() const { return properties_.online(); }
bool has_default_ipv4_route() const { return properties_.has_default_ipv4_route(); }
bool has_default_ipv6_route() const { return properties_.has_default_ipv6_route(); }
const ::std::vector<fuchsia::net::interfaces::Address>& addresses() const {
return properties_.addresses();
}
private:
explicit Properties(fuchsia::net::interfaces::Properties properties);
fuchsia::net::interfaces::Properties properties_;
};
// Move-only type which holds a collection of interface properties and can be updated with
// |fuchsia::net::interfaces::Event| events.
class PropertiesMap final {
public:
enum class UpdateErrorWithIdKind {
kDuplicateExisting,
kDuplicateAdded,
kUnknownChanged,
kUnknownRemoved,
};
template <UpdateErrorWithIdKind T>
struct UpdateErrorWithId {
uint64_t id;
bool operator==(const UpdateErrorWithId<T>& rhs) const { return id == rhs.id; }
};
enum class UpdateError {
kInvalidExisting,
kInvalidAdded,
kMissingId,
kInvalidChanged,
kInvalidEvent,
};
using UpdateErrorVariant =
std::variant<UpdateError, UpdateErrorWithId<UpdateErrorWithIdKind::kDuplicateExisting>,
UpdateErrorWithId<UpdateErrorWithIdKind::kDuplicateAdded>,
UpdateErrorWithId<UpdateErrorWithIdKind::kUnknownChanged>,
UpdateErrorWithId<UpdateErrorWithIdKind::kUnknownRemoved>>;
static std::string update_error_get_string(UpdateErrorVariant variant);
PropertiesMap() noexcept;
PropertiesMap(PropertiesMap&& interface) noexcept;
PropertiesMap& operator=(PropertiesMap&& interface) noexcept;
~PropertiesMap();
// Updates this properties map with |event|, returning an optional error.
fpromise::result<void, UpdateErrorVariant> Update(fuchsia::net::interfaces::Event event);
const std::unordered_map<uint64_t, Properties>& properties_map() const { return properties_map_; }
private:
std::unordered_map<uint64_t, Properties> properties_map_;
// Helper type for visitor in |update_error_get_string|.
template <class... Ts>
struct UpdateErrorVisitor : Ts... {
using Ts::operator()...;
};
template <class... Ts>
UpdateErrorVisitor(Ts...) -> UpdateErrorVisitor<Ts...>;
};
} // namespace net::interfaces
#endif // SRC_CONNECTIVITY_NETWORK_LIB_NET_INTERFACES_CPP_NET_INTERFACES_H_