aboutsummaryrefslogtreecommitdiffstats
path: root/apps/hiperf/src/forwarder_interface.h
blob: 7591ea2575efe1ca97d61e73a52b4fb76d14bb92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (c) 2021 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

extern "C" {
#ifndef WITH_POLICY
#define WITH_POLICY
#endif
#include <hicn/ctrl/api.h>
#include <hicn/util/ip_address.h>
}

#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>

#include <functional>
#include <thread>
#include <unordered_map>

namespace hiperf {

class ForwarderInterface {
  static const uint32_t REATTEMPT_DELAY_MS = 500;
  static const uint32_t MAX_REATTEMPT = 10;

 public:
  struct RouteInfo {
    int family;
    std::string local_addr;
    uint16_t local_port;
    std::string remote_addr;
    uint16_t remote_port;
    std::string route_addr;
    uint8_t route_len;
    std::string interface;
    std::string name;
  };

  using RouteInfoPtr = std::shared_ptr<RouteInfo>;

  class ICallback {
   public:
    virtual void onHicnServiceReady() = 0;
    virtual void onRouteConfigured(std::vector<RouteInfoPtr> &route_info) = 0;
  };

  enum class State {
    Disabled,  /* Stack is stopped */
    Requested, /* Stack is starting */
    Available, /* Forwarder is running */
    Connected, /* Control socket connected */
    Ready,     /* Listener present */
  };

 public:
  ForwarderInterface(asio::io_service &io_service, ICallback *callback);

  ~ForwarderInterface();

  State getState();

  void setState(State state);

  void onHicnServiceAvailable(bool flag);

  void enableCheckRoutesTimer();

  void createFaceAndRoutes(const std::vector<RouteInfoPtr> &routes_info);

  void createFaceAndRoute(const RouteInfoPtr &route_info);

  void deleteFaceAndRoutes(const std::vector<RouteInfoPtr> &routes_info);

  void deleteFaceAndRoute(const RouteInfoPtr &route_info);

  void close();

  uint16_t getHicnListenerPort() { return hicn_listen_port_; }

 private:
  int connectToForwarder();

  int checkListener();

  void internalCreateFaceAndRoutes(const std::vector<RouteInfoPtr> &route_info,
                                   uint8_t max_try, asio::steady_timer *timer);

  void internalDeleteFaceAndRoute(const RouteInfoPtr &routes_info);

  int tryToCreateFace(RouteInfo *RouteInfo, uint32_t *face_id);
  int tryToCreateRoute(RouteInfo *RouteInfo, uint32_t face_id);

  void checkRoutesLoop();

  void checkRoutes();

  asio::io_service &external_ioservice_;
  asio::io_service internal_ioservice_;
  ICallback *forwarder_interface_callback_;
  std::unique_ptr<asio::io_service::work> work_;
  hc_sock_t *sock_;
  std::unique_ptr<std::thread> thread_;
  //  SetRouteCallback set_route_callback_;
  // std::unordered_multimap<ProtocolPtr, RouteInfoPtr> route_status_;
  std::unique_ptr<asio::steady_timer> check_routes_timer_;
  uint32_t pending_add_route_counter_;
  uint16_t hicn_listen_port_;

  State state_;

  /* Reattempt timer */
  asio::steady_timer timer_;
  unsigned num_reattempts;
};

}  // namespace hiperf