summaryrefslogtreecommitdiffstats
path: root/libtransport/src/io_modules/udp
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar@cisco.com>2022-03-30 22:29:28 +0200
committerMauro Sardara <msardara@cisco.com>2022-03-31 19:51:47 +0200
commitc46e5df56b67bb8ea7a068d39324c640084ead2b (patch)
treeeddeb17785938e09bc42eec98ee09b8a28846de6 /libtransport/src/io_modules/udp
parent18fa668f25d3cc5463417ce7df6637e31578e898 (diff)
feat: boostrap hicn 22.02
The current patch provides several new features, improvements, bug fixes and also complete rewrite of entire components. - lib The hicn packet parser has been improved with a new packet format fully based on UDP. The TCP header is still temporarily supported but the UDP header will replace completely the new hicn packet format. Improvements have been made to make sure every packet parsing operation is made via this library. The current new header can be used as header between the payload and the UDP header or as trailer in the UDP surplus area to be tested when UDP options will start to be used. - hicn-light The portable packet forwarder has been completely rewritten from scratch with the twofold objective to improve performance and code size but also to drop dependencies such as libparc which is now removed by the current implementation. - hicn control the control library is the agent that is used to program the packet forwarders via their binary API. This component has benefited from significant improvements in terms of interaction model which is now event driven and more robust to failures. - VPP plugin has been updated to support VPP 22.02 - transport Major improvement have been made to the RTC protocol, to the support of IO modules and to the security sub system. Signed manifests are the default data authenticity and integrity framework. Confidentiality can be enabled by sharing the encryption key to the prod/cons layer. The library has been tested with group key based applications such as broadcast/multicast and real-time on-line meetings with trusted server keys or MLS. - testing Unit testing has been introduced using GoogleTest. One third of the code base is covered by unit testing with priority on critical features. Functional testing has also been introduce using Docker, linux bridging and Robot Framework to define test with Less Code techniques to facilitate the extension of the coverage. Co-authored-by: Mauro Sardara <msardara@cisco.com> Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com> Co-authored-by: Michele Papalini <micpapal@cisco.com> Co-authored-by: Angelo Mantellini <manangel@cisco.com> Co-authored-by: Jacques Samain <jsamain@cisco.com> Co-authored-by: Olivier Roques <oroques+fdio@cisco.com> Co-authored-by: Enrico Loparco <eloparco@cisco.com> Co-authored-by: Giulio Grassi <gigrassi@cisco.com> Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215 Signed-off-by: Luca Muscariello <muscariello@ieee.org> Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'libtransport/src/io_modules/udp')
-rw-r--r--libtransport/src/io_modules/udp/CMakeLists.txt32
-rw-r--r--libtransport/src/io_modules/udp/hicn_forwarder_module.cc181
-rw-r--r--libtransport/src/io_modules/udp/hicn_forwarder_module.h86
-rw-r--r--libtransport/src/io_modules/udp/udp_socket_connector.cc211
-rw-r--r--libtransport/src/io_modules/udp/udp_socket_connector.h88
5 files changed, 0 insertions, 598 deletions
diff --git a/libtransport/src/io_modules/udp/CMakeLists.txt b/libtransport/src/io_modules/udp/CMakeLists.txt
deleted file mode 100644
index b9c19d063..000000000
--- a/libtransport/src/io_modules/udp/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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.
-
-list(APPEND MODULE_HEADER_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_forwarder_module.h
- ${CMAKE_CURRENT_SOURCE_DIR}/udp_socket_connector.h
-)
-
-list(APPEND MODULE_SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_forwarder_module.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/udp_socket_connector.cc
-)
-
-build_module(hicnlight_module
- SHARED
- SOURCES ${MODULE_SOURCE_FILES}
- DEPENDS ${DEPENDENCIES}
- COMPONENT ${LIBTRANSPORT_COMPONENT}
- INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS}
- DEFINITIONS ${COMPILER_DEFINITIONS}
- COMPILE_OPTIONS ${COMPILE_FLAGS}
-)
diff --git a/libtransport/src/io_modules/udp/hicn_forwarder_module.cc b/libtransport/src/io_modules/udp/hicn_forwarder_module.cc
deleted file mode 100644
index ba08dd8c0..000000000
--- a/libtransport/src/io_modules/udp/hicn_forwarder_module.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2017-2020 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.
- */
-
-#include <io_modules/udp/hicn_forwarder_module.h>
-#include <io_modules/udp/udp_socket_connector.h>
-
-union AddressLight {
- uint32_t ipv4;
- struct in6_addr ipv6;
-};
-
-typedef struct {
- uint8_t message_type;
- uint8_t command_id;
- uint16_t length;
- uint32_t seq_num;
-} CommandHeader;
-
-typedef struct {
- uint8_t message_type;
- uint8_t command_id;
- uint16_t length;
- uint32_t seq_num;
- char symbolic_or_connid[16];
- union AddressLight address;
- uint16_t cost;
- uint8_t address_type;
- uint8_t len;
-} RouteToSelfCommand;
-
-typedef struct {
- uint8_t message_type;
- uint8_t command_id;
- uint16_t length;
- uint32_t seq_num;
- char symbolic_or_connid[16];
-} DeleteSelfConnectionCommand;
-
-namespace {
-static constexpr uint8_t addr_inet = 1;
-static constexpr uint8_t addr_inet6 = 2;
-static constexpr uint8_t add_route_command = 3;
-static constexpr uint8_t delete_connection_command = 5;
-static constexpr uint8_t request_light = 0xc0;
-static constexpr char identifier[] = "SELF";
-
-void fillCommandHeader(CommandHeader *header) {
- // Allocate and fill the header
- header->message_type = request_light;
- header->length = 1;
-}
-
-RouteToSelfCommand createCommandRoute(std::unique_ptr<sockaddr> &&addr,
- uint8_t prefix_length) {
- RouteToSelfCommand command = {0};
-
- // check and set IP address
- if (addr->sa_family == AF_INET) {
- command.address_type = addr_inet;
- command.address.ipv4 = ((sockaddr_in *)addr.get())->sin_addr.s_addr;
- } else if (addr->sa_family == AF_INET6) {
- command.address_type = addr_inet6;
- command.address.ipv6 = ((sockaddr_in6 *)addr.get())->sin6_addr;
- }
-
- // Fill remaining payload fields
-#ifndef _WIN32
- strcpy(command.symbolic_or_connid, identifier);
-#else
- strcpy_s(command.symbolic_or_connid, 16, identifier);
-#endif
- command.cost = 1;
- command.len = (uint8_t)prefix_length;
-
- // Allocate and fill the header
- command.command_id = add_route_command;
- fillCommandHeader((CommandHeader *)&command);
-
- return command;
-}
-
-DeleteSelfConnectionCommand createCommandDeleteConnection() {
- DeleteSelfConnectionCommand command = {0};
- fillCommandHeader((CommandHeader *)&command);
- command.command_id = delete_connection_command;
-
-#ifndef _WIN32
- strcpy(command.symbolic_or_connid, identifier);
-#else
- strcpy_s(command.symbolic_or_connid, 16, identifier);
-#endif
-
- return command;
-}
-
-} // namespace
-
-namespace transport {
-
-namespace core {
-
-HicnForwarderModule::HicnForwarderModule() : IoModule(), connector_(nullptr) {}
-
-HicnForwarderModule::~HicnForwarderModule() {}
-
-void HicnForwarderModule::connect(bool is_consumer) {
- connector_->connect();
- connector_->setRole(is_consumer ? Connector::Role::CONSUMER
- : Connector::Role::PRODUCER);
-}
-
-bool HicnForwarderModule::isConnected() { return connector_->isConnected(); }
-
-void HicnForwarderModule::send(Packet &packet) {
- IoModule::send(packet);
- packet.setChecksum();
- connector_->send(packet);
-}
-
-void HicnForwarderModule::send(const uint8_t *packet, std::size_t len) {
- counters_.tx_packets++;
- counters_.tx_bytes += len;
-
- // Perfect forwarding
- connector_->send(packet, len);
-}
-
-void HicnForwarderModule::registerRoute(const Prefix &prefix) {
- auto command = createCommandRoute(prefix.toSockaddr(),
- (uint8_t)prefix.getPrefixLength());
- send((uint8_t *)&command, sizeof(RouteToSelfCommand));
-}
-
-void HicnForwarderModule::closeConnection() {
- auto command = createCommandDeleteConnection();
- send((uint8_t *)&command, sizeof(DeleteSelfConnectionCommand));
- connector_->close();
-}
-
-void HicnForwarderModule::init(
- Connector::PacketReceivedCallback &&receive_callback,
- Connector::OnReconnectCallback &&reconnect_callback,
- asio::io_service &io_service, const std::string &app_name) {
- if (!connector_) {
- connector_ = new UdpSocketConnector(std::move(receive_callback), nullptr,
- nullptr, std::move(reconnect_callback),
- io_service, app_name);
- }
-}
-
-void HicnForwarderModule::processControlMessageReply(
- utils::MemBuf &packet_buffer) {
- if (packet_buffer.data()[0] == nack_code) {
- throw errors::RuntimeException(
- "Received Nack message from hicn light forwarder.");
- }
-}
-
-std::uint32_t HicnForwarderModule::getMtu() { return interface_mtu; }
-
-bool HicnForwarderModule::isControlMessage(const uint8_t *message) {
- return message[0] == ack_code || message[0] == nack_code;
-}
-
-extern "C" IoModule *create_module(void) { return new HicnForwarderModule(); }
-
-} // namespace core
-
-} // namespace transport
diff --git a/libtransport/src/io_modules/udp/hicn_forwarder_module.h b/libtransport/src/io_modules/udp/hicn_forwarder_module.h
deleted file mode 100644
index 845db73bf..000000000
--- a/libtransport/src/io_modules/udp/hicn_forwarder_module.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2017-2020 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
-
-#include <hicn/transport/core/io_module.h>
-#include <hicn/transport/core/prefix.h>
-
-namespace transport {
-
-namespace core {
-
-class UdpSocketConnector;
-
-class HicnForwarderModule : public IoModule {
- static constexpr uint8_t ack_code = 0xc2;
- static constexpr uint8_t nack_code = 0xc3;
- static constexpr std::uint16_t interface_mtu = 1500;
-
- public:
- union addressLight {
- uint32_t ipv4;
- struct in6_addr ipv6;
- };
-
- struct route_to_self_command {
- uint8_t messageType;
- uint8_t commandID;
- uint16_t length;
- uint32_t seqNum;
- char symbolicOrConnid[16];
- union addressLight address;
- uint16_t cost;
- uint8_t addressType;
- uint8_t len;
- };
-
- using route_to_self_command = struct route_to_self_command;
-
- HicnForwarderModule();
-
- ~HicnForwarderModule();
-
- void connect(bool is_consumer) override;
-
- void send(Packet &packet) override;
- void send(const uint8_t *packet, std::size_t len) override;
-
- bool isConnected() override;
-
- void init(Connector::PacketReceivedCallback &&receive_callback,
- Connector::OnReconnectCallback &&reconnect_callback,
- asio::io_service &io_service,
- const std::string &app_name = "Libtransport") override;
-
- void registerRoute(const Prefix &prefix) override;
-
- std::uint32_t getMtu() override;
-
- bool isControlMessage(const uint8_t *message) override;
-
- void processControlMessageReply(utils::MemBuf &packet_buffer) override;
-
- void closeConnection() override;
-
- private:
- UdpSocketConnector *connector_;
-};
-
-extern "C" IoModule *create_module(void);
-
-} // namespace core
-
-} // namespace transport
diff --git a/libtransport/src/io_modules/udp/udp_socket_connector.cc b/libtransport/src/io_modules/udp/udp_socket_connector.cc
deleted file mode 100644
index 1412d8c07..000000000
--- a/libtransport/src/io_modules/udp/udp_socket_connector.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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.
- */
-
-#ifdef _WIN32
-#include <hicn/transport/portability/win_portability.h>
-#endif
-
-#include <glog/logging.h>
-#include <hicn/transport/errors/errors.h>
-#include <hicn/transport/utils/object_pool.h>
-#include <io_modules/udp/udp_socket_connector.h>
-
-#include <thread>
-#include <vector>
-
-namespace transport {
-
-namespace core {
-
-UdpSocketConnector::UdpSocketConnector(
- PacketReceivedCallback &&receive_callback, PacketSentCallback &&packet_sent,
- OnCloseCallback &&close_callback, OnReconnectCallback &&on_reconnect,
- asio::io_service &io_service, std::string app_name)
- : Connector(std::move(receive_callback), std::move(packet_sent),
- std::move(close_callback), std::move(on_reconnect)),
- io_service_(io_service),
- socket_(io_service_),
- resolver_(io_service_),
- connection_timer_(io_service_),
- read_msg_(std::make_pair(nullptr, 0)),
- is_reconnection_(false),
- data_available_(false),
- app_name_(app_name) {}
-
-UdpSocketConnector::~UdpSocketConnector() {}
-
-void UdpSocketConnector::connect(std::string ip_address, std::string port) {
- endpoint_iterator_ = resolver_.resolve(
- {ip_address, port, asio::ip::resolver_query_base::numeric_service});
-
- state_ = Connector::State::CONNECTING;
- doConnect();
-}
-
-void UdpSocketConnector::send(const uint8_t *packet, std::size_t len) {
- socket_.async_send(asio::buffer(packet, len),
- [this](std::error_code ec, std::size_t /*length*/) {
- if (sent_callback_) {
- sent_callback_(this, ec);
- }
- });
-}
-
-void UdpSocketConnector::send(Packet &packet) {
- io_service_.post([this, _packet{packet.shared_from_this()}]() {
- bool write_in_progress = !output_buffer_.empty();
- output_buffer_.push_back(std::move(_packet));
- if (TRANSPORT_EXPECT_TRUE(state_ == Connector::State::CONNECTED)) {
- if (!write_in_progress) {
- doWrite();
- }
- } else {
- // Tell the handle connect it has data to write
- data_available_ = true;
- }
- });
-}
-
-void UdpSocketConnector::close() {
- if (io_service_.stopped()) {
- doClose();
- } else {
- io_service_.dispatch(std::bind(&UdpSocketConnector::doClose, this));
- }
-}
-
-void UdpSocketConnector::doClose() {
- if (state_ != Connector::State::CLOSED) {
- state_ = Connector::State::CLOSED;
- if (socket_.is_open()) {
- socket_.shutdown(asio::ip::tcp::socket::shutdown_type::shutdown_both);
- socket_.close();
- }
- }
-}
-
-void UdpSocketConnector::doWrite() {
- auto packet = output_buffer_.front().get();
- auto array = std::vector<asio::const_buffer>();
-
- const utils::MemBuf *current = packet;
- do {
- array.push_back(asio::const_buffer(current->data(), current->length()));
- current = current->next();
- } while (current != packet);
-
- socket_.async_send(std::move(array), [this](std::error_code ec,
- std::size_t length) {
- if (TRANSPORT_EXPECT_TRUE(!ec)) {
- output_buffer_.pop_front();
- if (!output_buffer_.empty()) {
- doWrite();
- }
- } else if (ec.value() == static_cast<int>(std::errc::operation_canceled)) {
- // The connection has been closed by the application.
- return;
- } else {
- LOG(ERROR) << ec.value() << " " << ec.message();
- tryReconnect();
- }
- });
-}
-
-void UdpSocketConnector::doRead() {
- read_msg_ = getRawBuffer();
- socket_.async_receive(
- asio::buffer(read_msg_.first, read_msg_.second),
- [this](std::error_code ec, std::size_t length) {
- if (TRANSPORT_EXPECT_TRUE(!ec)) {
- auto packet = getPacketFromBuffer(read_msg_.first, length);
- receive_callback_(this, *packet, std::make_error_code(std::errc(0)));
- doRead();
- } else if (ec.value() ==
- static_cast<int>(std::errc::operation_canceled)) {
- // The connection has been closed by the application.
- return;
- } else {
- LOG(ERROR) << ec.value() << " " << ec.message();
- tryReconnect();
- }
- });
-}
-
-void UdpSocketConnector::tryReconnect() {
- if (state_ == Connector::State::CONNECTED) {
- LOG(ERROR) << "Connection lost. Trying to reconnect...";
- state_ = Connector::State::CONNECTING;
- is_reconnection_ = true;
- io_service_.post([this]() {
- if (socket_.is_open()) {
- socket_.shutdown(asio::ip::tcp::socket::shutdown_type::shutdown_both);
- socket_.close();
- }
-
- doConnect();
- startConnectionTimer();
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- });
- }
-}
-
-void UdpSocketConnector::doConnect() {
- asio::async_connect(
- socket_, endpoint_iterator_,
- [this](std::error_code ec, udp::resolver::iterator) {
- if (!ec) {
- connection_timer_.cancel();
- state_ = Connector::State::CONNECTED;
- doRead();
-
- if (data_available_) {
- data_available_ = false;
- doWrite();
- }
-
- if (is_reconnection_) {
- is_reconnection_ = false;
- }
-
- on_reconnect_callback_(this);
- } else {
- doConnect();
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- }
- });
-}
-
-bool UdpSocketConnector::checkConnected() {
- return state_ == Connector::State::CONNECTED;
-}
-
-void UdpSocketConnector::startConnectionTimer() {
- connection_timer_.expires_from_now(std::chrono::seconds(60));
- connection_timer_.async_wait(std::bind(&UdpSocketConnector::handleDeadline,
- this, std::placeholders::_1));
-}
-
-void UdpSocketConnector::handleDeadline(const std::error_code &ec) {
- if (!ec) {
- io_service_.post([this]() {
- socket_.close();
- LOG(ERROR) << "Error connecting. Is the forwarder running?";
- });
- }
-}
-
-} // end namespace core
-
-} // end namespace transport
diff --git a/libtransport/src/io_modules/udp/udp_socket_connector.h b/libtransport/src/io_modules/udp/udp_socket_connector.h
deleted file mode 100644
index c483e14aa..000000000
--- a/libtransport/src/io_modules/udp/udp_socket_connector.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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
-
-#include <hicn/transport/config.h>
-#include <hicn/transport/core/asio_wrapper.h>
-#include <hicn/transport/core/connector.h>
-#include <hicn/transport/core/content_object.h>
-#include <hicn/transport/core/global_object_pool.h>
-#include <hicn/transport/core/interest.h>
-#include <hicn/transport/core/name.h>
-#include <hicn/transport/core/packet.h>
-#include <hicn/transport/utils/branch_prediction.h>
-
-#include <deque>
-
-namespace transport {
-namespace core {
-
-using asio::ip::udp;
-
-class UdpSocketConnector : public Connector {
- public:
- UdpSocketConnector(PacketReceivedCallback &&receive_callback,
- PacketSentCallback &&packet_sent,
- OnCloseCallback &&close_callback,
- OnReconnectCallback &&on_reconnect,
- asio::io_service &io_service,
- std::string app_name = "Libtransport");
-
- ~UdpSocketConnector() override;
-
- void send(Packet &packet) override;
-
- void send(const uint8_t *packet, std::size_t len) override;
-
- void close() override;
-
- void connect(std::string ip_address = "127.0.0.1", std::string port = "9695");
-
- private:
- void doConnect();
-
- void doRead();
-
- void doWrite();
-
- void doClose();
-
- bool checkConnected();
-
- private:
- void handleDeadline(const std::error_code &ec);
-
- void startConnectionTimer();
-
- void tryReconnect();
-
- asio::io_service &io_service_;
- asio::ip::udp::socket socket_;
- asio::ip::udp::resolver resolver_;
- asio::ip::udp::resolver::iterator endpoint_iterator_;
- asio::steady_timer connection_timer_;
-
- std::pair<uint8_t *, std::size_t> read_msg_;
-
- bool is_reconnection_;
- bool data_available_;
-
- std::string app_name_;
-};
-
-} // end namespace core
-
-} // end namespace transport