---
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::PlatformAddrRange](Classes/structllarp_1_1layers_1_1platform_1_1PlatformAddrRange.md)**  |
| struct | **[llarp::layers::platform::AddressMappingEntry](Classes/structllarp_1_1layers_1_1platform_1_1AddressMappingEntry.md)**  |
| struct | **[llarp::layers::platform::AddressMapping](Classes/structllarp_1_1layers_1_1platform_1_1AddressMapping.md)**  |
| 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 "platform_addr.hpp"

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

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

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

namespace llarp::layers::platform
{

  struct PlatformAddrRange
  {
    PlatformAddr lo, hi;

    IPRange
    to_ip_range() const;

    PlatformAddrRange() = default;
    constexpr PlatformAddrRange(PlatformAddr _lo, PlatformAddr _hi)
        : lo{std::move(_lo)}, hi{std::move(_hi)}
    {}
    explicit PlatformAddrRange(IPRange range);

    bool
    operator==(const PlatformAddrRange& other) const;
    bool
    operator!=(const PlatformAddrRange& other) const;
  };

  struct AddressMappingEntry
  {
    PlatformAddrRange src_range, dst_range;
  };

  struct AddressMapping
  {
    flow::FlowInfo flow_info;
    PlatformAddrRange src_range, dst_range;
    bool is_exit;
  };

  class AddrMapper
  {
    // remote flow mappings
    std::unordered_map<flow::FlowInfo, AddressMappingEntry> _addrs;

   public:
    PlatformAddr&
    autovivify(const flow::FlowInfo& remote);

    inline PlatformAddr&
    operator[](const flow::FlowInfo& remote)
    {
      return autovivify(remote);
    }

    void
    put(AddressMapping&&);

    void
    prune(flow::FlowLayer&);

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

    inline bool
    has_addr_for_flow(const flow::FlowInfo& flow) const
    {
      return get_addr_for_flow(flow) != std::nullopt;
    }

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

    template <typename Viewer_t>
    void
    view_all_entries(Viewer_t&& view) const
    {
      for (const auto& [flow_info, ent] : _addrs)
      {
        const auto& [src_lo, src_hi] = ent.src_range;
        const auto& [dst_lo, dst_hi] = ent.dst_range;

        if (not view(flow_info, src_lo, src_hi, dst_lo, dst_hi))
          return;
      }
    }

    template <typename Viewer_t>
    void
    remove_if(Viewer_t&& view)
    {
      auto itr = _addrs.begin();
      while (itr != _addrs.end())
      {
        if (view(itr->first, itr->second))
          itr = _addrs.erase(itr);
        else
          ++itr;
      }
    }

    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&);
}
```


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

Updated on 2023-02-24 at 15:57:37 +0000
