Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
http_proxy.h
1 /*
2  * Copyright (c) 2020 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <hicn/transport/interfaces/socket_consumer.h>
19 #include <hicn/transport/utils/event_thread.h>
20 
21 #include "forwarder_config.h"
22 #include "http_session.h"
23 #include "icn_receiver.h"
24 
25 #define ASIO_STANDALONE
26 #include <asio.hpp>
27 #include <asio/version.hpp>
28 #include <unordered_set>
29 
30 class TcpListener {
31  public:
32  using AcceptCallback = std::function<void(asio::ip::tcp::socket&&)>;
33 
34  TcpListener(asio::io_service& io_service, short port, AcceptCallback callback)
35  : acceptor_(io_service),
36 #if ((ASIO_VERSION / 100 % 1000) < 12)
37  socket_(io_service),
38 #endif
39  callback_(callback) {
40  acceptor_.open(asio::ip::tcp::v4());
41  typedef asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT>
42  reuse_port;
43  acceptor_.set_option(reuse_port(true));
44  acceptor_.bind(asio::ip::tcp::endpoint(
45  asio::ip::address::from_string("127.0.0.1"), port));
46  acceptor_.listen();
47  }
48 
49  public:
50  void doAccept() {
51 #if ((ASIO_VERSION / 100 % 1000) >= 12)
52  acceptor_.async_accept(
53  [this](std::error_code ec, asio::ip::tcp::socket socket) {
54 #else
55  acceptor_.async_accept(socket_, [this](std::error_code ec) {
56  auto socket = std::move(socket_);
57 #endif
58  if (!ec) {
59  callback_(std::move(socket));
60  doAccept();
61  }
62  });
63  }
64 
65  void stop() { acceptor_.close(); }
66 
67  asio::ip::tcp::acceptor acceptor_;
68 #if ((ASIO_VERSION / 100 % 1000) < 12)
69  asio::ip::tcp::socket socket_;
70 #endif
71  AcceptCallback callback_;
72 };
73 
74 namespace transport {
75 
76 class HTTPClientConnectionCallback;
77 
78 class Receiver {
79  public:
80  Receiver() : thread_() {}
81  virtual ~Receiver() = default;
82  void stopAndJoinThread() { thread_.stop(); }
83  virtual void stop() = 0;
84 
85  protected:
86  utils::EventThread thread_;
87 };
88 
89 class TcpReceiver : public Receiver {
90  friend class HTTPClientConnectionCallback;
91 
92  public:
93  TcpReceiver(std::uint16_t port, const std::string& prefix,
94  const std::string& ipv6_first_word);
95 
96  void stop() override;
97 
98  private:
99  void onNewConnection(asio::ip::tcp::socket&& socket);
100  void onClientDisconnect(HTTPClientConnectionCallback* client);
101 
102  template <typename Callback>
103  void parseHicnHeader(std::string& hicn_header, Callback&& callback) {
104  forwarder_config_.parseHicnHeader(hicn_header,
105  std::forward<Callback>(callback));
106  }
107 
108  TcpListener listener_;
109  std::string prefix_;
110  std::string ipv6_first_word_;
111  std::string prefix_hash_;
112  std::deque<HTTPClientConnectionCallback*> http_clients_;
113  std::unordered_set<HTTPClientConnectionCallback*> used_http_clients_;
114  ForwarderConfig forwarder_config_;
115  bool stopped_;
116 };
117 
118 class IcnReceiver : public Receiver {
119  public:
120  template <typename... Args>
121  IcnReceiver(Args&&... args)
122  : Receiver(),
123  icn_consum_producer_(thread_.getIoService(),
124  std::forward<Args>(args)...) {
125  icn_consum_producer_.run();
126  }
127 
128  void stop() override {
129  thread_.add([this]() {
130  /* Stop the listener */
131  icn_consum_producer_.stop();
132  });
133  }
134 
135  private:
136  AsyncConsumerProducer icn_consum_producer_;
137 };
138 
139 class HTTPProxy {
140  public:
141  enum Server { CREATE };
142  enum Client { WRAP_BUFFER };
143 
144  struct CommonParams {
145  std::string prefix;
146  std::string first_ipv6_word;
147 
148  virtual void printParams() { std::cout << "Parameters: " << std::endl; };
149  };
150 
151  struct ClientParams : virtual CommonParams {
152  short tcp_listen_port;
153  void printParams() override {
154  std::cout << "Running HTTP/TCP -> HTTP/hICN proxy." << std::endl;
155  CommonParams::printParams();
156  std::cout << "\t"
157  << "HTTP listen port: " << tcp_listen_port << std::endl;
158  std::cout << "\t"
159  << "Consumer Prefix: " << prefix << std::endl;
160  std::cout << "\t"
161  << "Prefix first word: " << first_ipv6_word << std::endl;
162  }
163  };
164 
165  struct ServerParams : virtual CommonParams {
166  std::string origin_address;
167  std::string origin_port;
168  std::string cache_size;
169  std::string mtu;
170  std::string content_lifetime;
171  bool manifest;
172 
173  void printParams() override {
174  std::cout << "Running HTTP/hICN -> HTTP/TCP proxy." << std::endl;
175  CommonParams::printParams();
176  std::cout << "\t"
177  << "Origin address: " << origin_address << std::endl;
178  std::cout << "\t"
179  << "Origin port: " << origin_port << std::endl;
180  std::cout << "\t"
181  << "Producer cache size: " << cache_size << std::endl;
182  std::cout << "\t"
183  << "hICN MTU: " << mtu << std::endl;
184  std::cout << "\t"
185  << "Default content lifetime: " << content_lifetime
186  << std::endl;
187  std::cout << "\t"
188  << "Producer Prefix: " << prefix << std::endl;
189  std::cout << "\t"
190  << "Prefix first word: " << first_ipv6_word << std::endl;
191  std::cout << "\t"
192  << "Use manifest: " << manifest << std::endl;
193  }
194  };
195 
196  HTTPProxy(ClientParams& icn_params, std::size_t n_thread = 1);
197  HTTPProxy(ServerParams& icn_params, std::size_t n_thread = 1);
198 
199  void run() { main_io_context_.run(); }
200  void stop();
201 
202  private:
203  void setupSignalHandler();
204 
205  std::vector<std::unique_ptr<Receiver>> receivers_;
206  asio::io_service main_io_context_;
207  asio::signal_set signals_;
208 };
209 
210 } // namespace transport
transport::Receiver
Definition: http_proxy.h:78
transport::AsyncConsumerProducer
Definition: icn_receiver.h:32
utils::EventThread
Definition: event_thread.h:27
transport::HTTPProxy::CommonParams
Definition: http_proxy.h:144
transport::IcnReceiver
Definition: http_proxy.h:118
transport
Definition: forwarder_config.h:32
transport::HTTPProxy::ClientParams
Definition: http_proxy.h:151
transport::HTTPProxy
Definition: http_proxy.h:139
transport::TcpReceiver
Definition: http_proxy.h:89
TcpListener
Definition: http_proxy.h:30
transport::ForwarderConfig
Definition: forwarder_config.h:40
transport::HTTPProxy::ServerParams
Definition: http_proxy.h:165