Skip to content

Commit

Permalink
Implement Tls server
Browse files Browse the repository at this point in the history
  • Loading branch information
Iandiehard committed Mar 26, 2024
1 parent e212840 commit df07f09
Show file tree
Hide file tree
Showing 10 changed files with 446 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* Diagnostic Client library
* Copyright (C) 2024 Avijit Dey
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_ACCEPTOR_H_
#define DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_ACCEPTOR_H_

#include "boost-support/server/tls/tls_server.h"

namespace boost_support {
namespace server {
namespace tls {

/**
* @brief The acceptor to create new tcp servers
*/
class TlsAcceptor final {
public:
/**
* @brief Constructs an instance of Acceptor
* @details Tcp connection shall be accepted on this ip address and port
* @param[in] local_ip_address
* The local ip address
* @param[in] local_port_num
* The local port number
* @param[in] maximum_connection
* The maximum number of accepted connection allowed
*/
TlsAcceptor(std::string_view local_ip_address, std::uint16_t local_port_num,
std::uint8_t maximum_connection) noexcept;

/**
* @brief Destruct an instance of TcpAcceptor
*/
~TlsAcceptor() noexcept;

/**
* @brief Get a tls server ready to communicate
* @details This blocks until new server is created
* @return Tls server object on success, else nothing
*/
std::optional<TlsServer> GetTlsServer() noexcept;

private:
/**
* @brief Forward declaration of tls acceptor implementation
*/
class TlsAcceptorImpl;

/**
* @brief Unique pointer to tls acceptor implementation
*/
std::unique_ptr<TlsAcceptorImpl> tls_acceptor_impl_;
};
} // namespace tls
} // namespace server
} // namespace boost_support
#endif // DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_ACCEPTOR_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Diagnostic Client library
* Copyright (C) 2024 Avijit Dey
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_SERVER_H_
#define DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_SERVER_H_

#include <functional>
#include <memory>

#include "boost-support/message/tcp/tcp_message.h"
#include "core/include/result.h"

namespace boost_support {
namespace socket {
namespace tls {
class TlsSocket;
} // namespace tls
} // namespace socket

namespace server {
namespace tls {

/**
* @brief Server that manages unsecured/ secured tcp connection
*/
class TlsServer final {
public:
/**
* @brief Type alias for tcp unsecured socket
*/
using TlsSocket = socket::tls::TlsSocket;

/**
* @brief Type alias for Tcp message
*/
using Message = boost_support::message::tcp::TcpMessage;

/**
* @brief Type alias for Tcp message pointer
*/
using MessagePtr = boost_support::message::tcp::TcpMessagePtr;

/**
* @brief Type alias for Tcp message const pointer
*/
using MessageConstPtr = boost_support::message::tcp::TcpMessageConstPtr;

/**
* @brief Tcp function template used for reception
*/
using HandlerRead = std::function<void(MessagePtr)>;

public:
/**
* @brief Constructs an instance of TlsServer
* @param[in] tls_socket
* The underlying tls socket required for communication
*/
explicit TlsServer(TlsSocket tls_socket) noexcept;

/**
* @brief Deleted copy assignment and copy constructor
*/
TlsServer(const TlsServer &other) noexcept = delete;
TlsServer &operator=(const TlsServer &other) noexcept = delete;

/**
* @brief Move assignment and move constructor
*/
TlsServer(TlsServer &&other) noexcept;
TlsServer &operator=(TlsServer &&other) noexcept;

/**
* @brief Destruct an instance of TcpServer
*/
~TlsServer() noexcept;

/**
* @brief Initialize the server
*/
void Initialize() noexcept;

/**
* @brief De-initialize the server
*/
void DeInitialize() noexcept;

/**
* @brief Function to set the read handler that is invoked when message is received
* @details The ownership of provided read handler is moved
* @param[in] read_handler
* The handler to be set
*/
void SetReadHandler(HandlerRead read_handler) noexcept;

/**
* @brief Function to transmit the provided tcp message
* @param[in] tcp_message
* The tcp message
* @return Empty void on success, otherwise error is returned
*/
core_type::Result<void> Transmit(MessageConstPtr tcp_message);

private:
/**
* @brief Forward declaration of tcp server implementation
*/
class TlsServerImpl;

/**
* @brief Unique pointer to tcp server implementation
*/
std::unique_ptr<TlsServerImpl> tls_server_impl_;
};

} // namespace tls
} // namespace server
} // namespace boost_support
#endif // DIAG_CLIENT_LIB_LIB_BOOST_SUPPORT_INCLUDE_BOOST_SUPPORT_SERVER_TLS_TLS_SERVER_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* Diagnostic Client library
* Copyright (C) 2024 Avijit Dey
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

// includes
#include <boost/asio.hpp>

#include "boost-support/common/logger.h"
#include "boost-support/server/tcp/tcp_acceptor.h"
#include "boost-support/socket/tcp/tcp_socket.h"

namespace boost_support {
namespace server {
namespace tcp {
namespace {
/**
* @brief Type alias for tcp protocol
*/
using Tcp = boost::asio::ip::tcp;

/**
* @brief Type alias for tcp ip address
*/
using TcpIpAddress = boost::asio::ip::address;

} // namespace

class TcpAcceptor::TcpAcceptorImpl final {
public:
/**
* @brief Type alias for tcp unsecured socket
*/
using TcpSocket = socket::tcp::TcpSocket;

public:
/**
* @brief Constructs an instance of Acceptor
* @details Tcp connection shall be accepted on this ip address and port
* @param[in] local_ip_address
* The local ip address
* @param[in] local_port_num
* The local port number
* @param[in] maximum_connection
* The maximum number of accepted connection
*/
TcpAcceptorImpl(std::string_view local_ip_address, std::uint16_t local_port_num,
std::uint8_t maximum_connection) noexcept
: io_context_{},
acceptor_{io_context_,
Tcp::endpoint(TcpIpAddress::from_string(std::string{local_ip_address}.c_str()), local_port_num)} {
acceptor_.listen(maximum_connection);
}

/**
* @brief Get a tcp server ready to communicate
* @details This blocks until new server is created
* @return Tcp server object on success, else nothing
*/
std::optional<TcpServer> GetTcpServer() noexcept {
using TcpErrorCodeType = boost::system::error_code;
std::optional<TcpServer> tcp_server{};
TcpErrorCodeType ec{};
Tcp::endpoint endpoint{};

// blocking accept
TcpSocket::Socket accepted_socket{acceptor_.accept(endpoint, ec)};
if (ec.value() == boost::system::errc::success) {
tcp_server.emplace(TcpSocket{std::move(accepted_socket)});
common::logger::LibBoostLogger::GetLibBoostLogger().GetLogger().LogDebug(
__FILE__, __LINE__, __func__, [&endpoint](std::stringstream &msg) {
msg << "Tcp socket connection received from client "
<< "<" << endpoint.address().to_string() << "," << endpoint.port() << ">";
});
} else {
common::logger::LibBoostLogger::GetLibBoostLogger().GetLogger().LogError(
__FILE__, __LINE__, __func__,
[ec](std::stringstream &msg) { msg << "Tcp socket accept failed with error: " << ec.message(); });
}
return tcp_server;
}

private:
/**
* @brief Type alias for tcp acceptor
*/
using Acceptor = boost::asio::ip::tcp::acceptor;

/**
* @brief Store the io context
*/
boost::asio::io_context io_context_;

/**
* @brief Store the tcp acceptor
*/
Acceptor acceptor_;
};

TcpAcceptor::TcpAcceptor(std::string_view local_ip_address, std::uint16_t local_port_num,
std::uint8_t maximum_connection) noexcept
: tcp_acceptor_impl_{std::make_unique<TcpAcceptorImpl>(local_ip_address, local_port_num, maximum_connection)} {}

TcpAcceptor::~TcpAcceptor() noexcept = default;

std::optional<TcpServer> TcpAcceptor::GetTcpServer() noexcept { return tcp_acceptor_impl_->GetTcpServer(); }

} // namespace tcp
} // namespace server
} // namespace boost_support

0 comments on commit df07f09

Please sign in to comment.