---
title: llarp/layers/platform/addr_mapper.hpp

---

# llarp/layers/platform/addr_mapper.hpp



## Namespaces

| Name           |
| -------------- |
| **[llarp](Namespaces/namespacellarp.md)** <br>[crypto.hpp] |
| **[llarp::layers](Namespaces/namespacellarp_1_1layers.md)**  |
| **[llarp::layers::flow](Namespaces/namespacellarp_1_1layers_1_1flow.md)**  |
| **[llarp::layers::platform](Namespaces/namespacellarp_1_1layers_1_1platform.md)**  |

## Classes

|                | Name           |
| -------------- | -------------- |
| struct | **[llarp::layers::platform::AddressMapping](Classes/structllarp_1_1layers_1_1platform_1_1AddressMapping.md)**  |
| class | **[llarp::layers::platform::AddressMappingEntry](Classes/classllarp_1_1layers_1_1platform_1_1AddressMappingEntry.md)** <br>container that holds an addressmapping and extra metadata we need in the addrmapper.  |
| class | **[llarp::layers::platform::AddrMapper](Classes/classllarp_1_1layers_1_1platform_1_1AddrMapper.md)** <br>in charge of mapping flow addresses and platform addresses to each other  |




## Source code

```cpp
#pragma once

#include "llarp/net/ip_range.hpp"
#include "llarp/net/net_int.hpp"
#include "platform_addr.hpp"

#include <chrono>
#include <llarp/layers/flow/flow_info.hpp>

#include <nlohmann/json_fwd.hpp>
#include <string>
#include <optional>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

namespace llarp::layers::flow
{
  class FlowLayer;
}

namespace llarp::layers::platform
{

  class AddrMapper;

  struct AddressMapping
  {
    std::optional<flow::FlowInfo> flow_info;
    PlatformAddr src, dst;
    std::vector<IPRange> owned_ranges;

    bool
    owns_range(const IPRange& range) const;

    std::string
    ToString() const;
  };

  class AddressMappingEntry
  {
    std::chrono::steady_clock::time_point _last_used_at;
    AddressMapping _entry;

   public:
    bool
    has_addr(const PlatformAddr& src, const PlatformAddr& dst) const;

    bool
    has_flow_info(const flow::FlowInfo& flow_info) const;

    inline auto
    idle_for() const
    {
      return decltype(_last_used_at)::clock::now() - _last_used_at;
    }

    constexpr const auto&
    last_used_at() const
    {
      return _last_used_at;
    }

    AddressMapping&
    access();

    const AddressMapping&
    view() const;
  };

  class AddrMapper
  {
    // remote flow mappings
    std::vector<AddressMappingEntry> _addrs;

    const IPRange _our_range;

    void
    remove_lru();

    PlatformAddr
    next_addr();

    friend class ReservedAddressMapping;

   public:
    explicit AddrMapper(const IPRange& range);

    const IPRange range;

    void
    put(AddressMapping&&);

    void
    prune(flow::FlowLayer&);

    std::optional<AddressMapping>
    get_addr_for_flow(const flow::FlowInfo& flow);

    bool
    has_addr_for_flow(const flow::FlowInfo& flow) const;

    std::optional<AddressMapping>
    mapping_for(const PlatformAddr& src, const PlatformAddr& dst);

    bool
    is_full() const;

    AddressMapping&
    allocate_mapping(std::optional<PlatformAddr> src = std::nullopt);

    template <typename Viewer_t>
    void
    view_all_entries(Viewer_t&& visit) const
    {
      for (const auto& ent : _addrs)
      {
        if (not visit(ent.view()))
          return;
      }
    }

    template <typename Predicate_t>
    [[nodiscard]] auto
    find_if(Predicate_t&& pred)
    {
      return std::find_if(
          _addrs.begin(), _addrs.end(), [pred](const auto& ent) { return pred(ent.view()); });
    }

    template <typename Predicate_t>
    [[nodiscard]] auto
    find_if(Predicate_t&& pred) const
    {
      return std::find_if(
          _addrs.begin(), _addrs.end(), [pred](const auto& ent) { return pred(ent.view()); });
    }

    template <typename Predicate_t>
    void
    remove_if_entry(Predicate_t&& pred)
    {
      auto itr = _addrs.begin();
      while (itr != _addrs.end())
      {
        if (pred(*itr))
          itr = _addrs.erase(itr);
        else
          ++itr;
      }
    }

    template <typename Predicate_t>
    void
    remove_if_mapping(Predicate_t&& pred)
    {
      remove_if_entry([pred](auto& ent) { return pred(ent.view()); });
    }

    std::vector<AddressMapping>
    all_exits() const;

    net::IPRangeMap<flow::FlowAddr>
    exit_map() const;
  };

}  // namespace llarp::layers::platform

namespace llarp
{
  nlohmann::json
  to_json(const llarp::layers::platform::AddressMapping&);

  template <>
  inline constexpr bool IsToStringFormattable<layers::platform::AddressMapping> = true;
}  // namespace llarp
```


-------------------------------

Updated on 2023-03-06 at 20:36:34 +0000
