Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## Author Francois Michaut
##
## Started on Thu May 26 23:23:59 2022 Francois Michaut
## Last update Mon Aug 18 17:26:23 2025 Francois Michaut
## Last update Thu May 14 04:43:48 2026 Francois Michaut
##
## CMakeLists.txt : CMake to build the FileShareProtocol library
##
Expand Down Expand Up @@ -35,6 +35,7 @@ add_library(fsp
source/Config/ServerConfig.cpp

source/Errors/TransferErrors.cpp
source/Errors/ConfigErrors.cpp

source/Peer/Peer.cpp
source/Peer/PeerBase.cpp
Expand Down
4 changes: 2 additions & 2 deletions include/FileShare/Config/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Tue Sep 13 11:23:57 2022 Francois Michaut
** Last update Fri Aug 22 18:59:52 2025 Francois Michaut
** Last update Thu May 14 05:03:33 2026 Francois Michaut
**
** Config.hpp : Configuration of the file sharing
*/
Expand Down Expand Up @@ -35,7 +35,7 @@ namespace FileShare {
auto set_downloads_folder(const std::filesystem::path &path) -> Config &;

auto set_file_mapping(FileMapping mapping) -> Config & { m_filemap = std::move(mapping); return *this; }
auto get_file_mapping() const -> const FileMapping & { return m_filemap; }
[[nodiscard]] auto get_file_mapping() const -> const FileMapping & { return m_filemap; }
auto get_file_mapping() -> FileMapping & { return m_filemap; }

[[nodiscard]] auto get_transport_mode() const -> TransportMode { return m_transport_mode; }
Expand Down
55 changes: 53 additions & 2 deletions include/FileShare/Config/Serialization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,40 @@
** Author Francois Michaut
**
** Started on Sun Dec 10 10:56:44 2023 Francois Michaut
** Last update Sat Aug 23 20:42:50 2025 Francois Michaut
** Last update Fri Jun 12 03:23:08 2026 Francois Michaut
**
** Serialization.hpp : FileShare Config serialization functions
*/

#pragma once

#include "CppSockets/Address.hpp"
#include "CppSockets/IPv4.hpp"
#include "FileShare/Config/Config.hpp"
#include "FileShare/Config/ServerConfig.hpp"

#include <cereal/access.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/filesystem.hpp>
#include <cereal/types/polymorphic.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/unordered_map.hpp>
#include <cereal/types/unordered_set.hpp>

static constexpr std::uint32_t FILE_SHARE_CONFIG_VERSION = 0;
static constexpr std::uint32_t FILE_SHARE_SERVER_CONFIG_VERSION = 0;
static constexpr std::uint32_t FILE_SHARE_SERVER_CONFIG_VERSION = 1;
static constexpr std::uint32_t FILE_SHARE_FILE_MAPPING_VERSION = 0;
static constexpr std::uint32_t FILE_SHARE_PATH_NODE_VERSION = 0;
static constexpr std::uint32_t CPP_SOCKETS_ENDPOINT_VERSION = 0;

CEREAL_CLASS_VERSION(FileShare::Config, FILE_SHARE_CONFIG_VERSION); // NOLINT
CEREAL_CLASS_VERSION(FileShare::ServerConfig, FILE_SHARE_SERVER_CONFIG_VERSION); // NOLINT
CEREAL_CLASS_VERSION(FileShare::FileMapping, FILE_SHARE_FILE_MAPPING_VERSION); // NOLINT
CEREAL_CLASS_VERSION(FileShare::RootPathNode, FILE_SHARE_PATH_NODE_VERSION); // NOLINT
CEREAL_CLASS_VERSION(FileShare::PathNode, FILE_SHARE_PATH_NODE_VERSION); // NOLINT
CEREAL_CLASS_VERSION(CppSockets::EndpointV4, CPP_SOCKETS_ENDPOINT_VERSION); // NOLINT

CEREAL_REGISTER_POLYMORPHIC_RELATION(CppSockets::IEndpoint, CppSockets::EndpointV4);

// TODO: Make a custom cereal archive for .conf files : https://uscilab.github.io/cereal/serialization_archives.html#adding-more-archives
// Use .conf files for Config and ServerConfig
Expand All @@ -43,6 +51,12 @@ namespace FileShare {
}

if (version == FILE_SHARE_SERVER_CONFIG_VERSION) {
archive(
config.m_uuid, config.m_device_name, config.m_private_keys_dir,
config.m_private_key_name, config.m_disable_server, config.m_server_endpoint
);
} else if (version == 0) {
// Defaults Server Endpoint
archive(
config.m_uuid, config.m_device_name, config.m_private_keys_dir,
config.m_private_key_name, config.m_disable_server
Expand Down Expand Up @@ -92,3 +106,40 @@ namespace FileShare {
}
}
}

namespace cereal {
template <class Archive>
void serialize(Archive &archive, CppSockets::EndpointV4 &endpoint, const std::uint32_t version) {
if (version > CPP_SOCKETS_ENDPOINT_VERSION) {
throw std::runtime_error("Endpoint file format is more recent than what this program supports");
}

if (version == CPP_SOCKETS_ENDPOINT_VERSION) {
archive(endpoint.get_addr().to_string(), endpoint.get_port());
} else {
throw std::runtime_error("FileMapping file format is unsupported");
}
}

template <> struct LoadAndConstruct<CppSockets::EndpointV4> {
template <class Archive>
static void load_and_construct(Archive &archive, cereal::construct<CppSockets::EndpointV4> &construct, std::uint32_t const version) {
if (version > CPP_SOCKETS_ENDPOINT_VERSION) {
throw std::runtime_error("Endpoint file format is more recent than what this program supports");
}

if (version == CPP_SOCKETS_ENDPOINT_VERSION) {
std::string addr;
std::uint16_t port;

archive(addr, port);
CppSockets::IPv4 ipv4(addr.c_str());

construct(ipv4, port);
} else {
throw std::runtime_error("FileMapping file format is unsupported");
}

}
};
}
15 changes: 13 additions & 2 deletions include/FileShare/Config/ServerConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
** Author Francois Michaut
**
** Started on Wed Aug 6 15:09:50 2025 Francois Michaut
** Last update Fri Aug 22 20:41:53 2025 Francois Michaut
** Last update Fri Jun 12 04:06:14 2026 Francois Michaut
**
** ServerConfig.hpp : Server Configuration
*/

#pragma once

#include "CppSockets/Address.hpp"
#include <CppSockets/IPv4.hpp>

#include <filesystem>

namespace FileShare {
Expand All @@ -22,6 +25,7 @@ namespace FileShare {
static constexpr std::filesystem::perms SECURE_FOLDER_PERMS = std::filesystem::perms::owner_all;

static auto default_private_keys_dir() -> const std::filesystem::path &;
static auto default_endpoint() -> std::shared_ptr<CppSockets::IEndpoint>;

// paths starting with '~/' will have this part replaced by the current user's home directory
static auto load(std::filesystem::path config_file = "") -> ServerConfig;
Expand All @@ -39,6 +43,10 @@ namespace FileShare {
[[nodiscard]] auto is_server_disabled() const -> bool { return m_disable_server; }
auto set_server_disabled(bool disabled) -> ServerConfig & { m_disable_server = disabled; return *this; }

[[nodiscard]] auto get_server_endpoint() const -> const CppSockets::IEndpoint & { return *m_server_endpoint; }
auto set_server_endpoint(std::shared_ptr<CppSockets::IEndpoint> endpoint) -> ServerConfig & { m_server_endpoint = std::move(endpoint); return *this; }
auto set_server_endpoint(std::string_view endpoint) -> ServerConfig & { m_server_endpoint = CppSockets::IEndpoint::from_string(endpoint) ; return *this; }

void validate_config() const;
private:
template <class Archive>
Expand Down Expand Up @@ -67,7 +75,10 @@ namespace FileShare {
// Set this to true if you want an extra layer of security by
// preventing external connections.
// Note that when you initiate a connection to another server it will
// be able to send commands as well.
// still be able to send commands to you as well.
bool m_disable_server = false;

// When server is enabled, this is the endpoint it listens to.
std::shared_ptr<CppSockets::IEndpoint> m_server_endpoint = ServerConfig::default_endpoint();
};
}
2 changes: 1 addition & 1 deletion include/FileShare/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Sun Oct 22 13:22:53 2023 Francois Michaut
** Last update Sun Oct 22 13:27:05 2023 Francois Michaut
** Last update Sat May 16 11:22:42 2026 Francois Michaut
**
** Error.hpp : Generic Error class
*/
Expand Down
27 changes: 27 additions & 0 deletions include/FileShare/Errors/ConfigErrors.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
** Project LibFileShareProtocol, 2026
**
** Author Francois Michaut
**
** Started on Thu May 14 04:34:25 2026 Francois Michaut
** Last update Sat May 16 11:16:25 2026 Francois Michaut
**
** ConfigErrors.hpp : Config related errors
*/

#pragma once

#include "FileShare/Error.hpp"

#include <string>

namespace FileShare::Errors::Config {
class NotFoundError : public FileShare::Error {
public:
NotFoundError(const char *path);
NotFoundError(std::string path);

private:
std::string m_path;
};
}
5 changes: 3 additions & 2 deletions include/FileShare/Peer/Peer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Sun Aug 28 09:23:07 2022 Francois Michaut
** Last update Sat Aug 23 00:08:01 2025 Francois Michaut
** Last update Wed May 27 09:12:59 2026 Francois Michaut
**
** Peer.hpp : Client to communicate with peers using the FileShareProtocol
*/
Expand Down Expand Up @@ -34,8 +34,9 @@ namespace FileShare {

// TODO: Allow copy ? What would that even mean ?
Peer(const Peer &) = delete;
Peer(Peer &&) = default;
auto operator=(const Peer &) -> Peer & = delete;

Peer(Peer &&) = default;
auto operator=(Peer &&) -> Peer & = default;

~Peer() override = default;
Expand Down
32 changes: 17 additions & 15 deletions include/FileShare/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Mon Aug 29 19:01:51 2022 Francois Michaut
** Last update Fri Aug 22 00:39:26 2025 Francois Michaut
** Last update Fri Jun 12 01:04:34 2026 Francois Michaut
**
** Server.hpp : Server part used to receive qnd process requests of Peers
*/
Expand Down Expand Up @@ -35,7 +35,7 @@ namespace FileShare {
public:
class Event {
public:
enum Type {
enum Type : std::uint8_t {
NONE,
CONNECT,
REQUEST
Expand All @@ -53,6 +53,10 @@ namespace FileShare {
auto type() -> Type & { return m_type; }
auto peer() -> PeerBase_ptr & { return m_peer; }
auto request() -> std::optional<Protocol::Request> & { return m_request; }

[[nodiscard]] auto is_request() const -> bool { return m_type == REQUEST; }
[[nodiscard]] auto is_connect() const -> bool { return m_type == CONNECT; }
[[nodiscard]] auto is_none() const -> bool { return m_type == NONE; }
private:
Type m_type = NONE;
PeerBase_ptr m_peer;
Expand All @@ -71,7 +75,7 @@ namespace FileShare {
using FdVector = std::vector<struct pollfd>;

Server(
std::shared_ptr<CppSockets::IEndpoint> server_endpoint = Server::default_endpoint(),
std::shared_ptr<CppSockets::IEndpoint> server_endpoint = ServerConfig::default_endpoint(),
ServerConfig config = Server::default_config(),
Config peer_config = Server::default_peer_config()
);
Expand Down Expand Up @@ -100,30 +104,30 @@ namespace FileShare {

void accept_peer(PreAuthPeer_ptr peer, bool temporary_trust = false);

auto get_config() -> ServerConfig & { return m_config; }
auto get_config() const -> const ServerConfig & { return m_config; }
[[nodiscard]] auto get_config() -> ServerConfig & { return m_config; }
[[nodiscard]] auto get_config() const -> const ServerConfig & { return m_config; }
void set_config(const ServerConfig &config) { m_config = config; }

// Warning : changing the default peer configuration does NOT
// change the already connected Peers, only new ones. You need to
// manually update the configuration of each existing peer.
auto get_peer_config() -> Config & { return m_peer_config; }
auto get_peer_config() const -> const Config & { return m_peer_config; }
[[nodiscard]] auto get_peer_config() -> Config & { return m_peer_config; }
[[nodiscard]] auto get_peer_config() const -> const Config & { return m_peer_config; }
void set_peer_config(const Config &config) { m_peer_config = config; }

static auto default_config() -> ServerConfig;
static auto default_peer_config() -> Config;

auto get_server_endpoint() const -> const CppSockets::IEndpoint & { return *m_server_endpoint; }
auto get_socket() const -> const CppSockets::TlsSocket & { return m_socket; }
[[nodiscard]] auto get_server_endpoint() const -> const CppSockets::IEndpoint & { return *m_server_endpoint; }
[[nodiscard]] auto get_socket() const -> const CppSockets::TlsSocket & { return m_socket; }

auto get_peers() const -> const PeerMap & { return m_peers; }
auto get_pending_peers() const -> const PreAuthPeerMap & { return m_pending_authorization_peers; }
[[nodiscard]] auto get_peers() const -> const PeerMap & { return m_peers; }
[[nodiscard]] auto get_pending_peers() const -> const PreAuthPeerMap & { return m_pending_authorization_peers; }

auto get_poll_fds() const -> const FdVector & { return m_fds; }
[[nodiscard]] auto get_poll_fds() const -> const FdVector & { return m_fds; }

void restart();
auto disabled() const -> bool { return m_config.is_server_disabled(); }
[[nodiscard]] auto disabled() const -> bool { return m_config.is_server_disabled(); }
void set_disabled(bool disabled);
private:
void initialize_private_key();
Expand All @@ -135,8 +139,6 @@ namespace FileShare {
auto insert_peer(PreAuthPeer_ptr &&peer) -> Peer_ptr &;
auto insert_peer(Peer_ptr peer) -> Peer_ptr &;

static auto default_endpoint() -> std::shared_ptr<CppSockets::IEndpoint>;

std::shared_ptr<CppSockets::IEndpoint> m_server_endpoint;
CppSockets::TlsContext m_ctx;
CppSockets::TlsSocket m_socket;
Expand Down
13 changes: 10 additions & 3 deletions source/Config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
** Author Francois Michaut
**
** Started on Tue Sep 13 11:29:35 2022 Francois Michaut
** Last update Sun Aug 24 19:46:07 2025 Francois Michaut
** Last update Fri Jun 12 03:00:33 2026 Francois Michaut
**
** FileShareConfig.cpp : FileShareConfig implementation
*/

#include "FileShare/Config/Config.hpp"
#include "FileShare/Config/Serialization.hpp" // NOLINT(misc-include-cleaner,unused-includes)
#include "FileShare/Errors/ConfigErrors.hpp"
#include "FileShare/Utils/Path.hpp"

#include <cereal/archives/binary.hpp>

#include <cstdio>
#include <filesystem>
#include <fstream>

Expand All @@ -42,9 +42,16 @@ namespace FileShare {

Config config(false);
config.m_filepath = FileShare::Utils::resolve_home_component(config_file);
std::ifstream file(config.m_filepath, std::ios_base::binary | std::ios_base::in);

std::ifstream file(config.m_filepath,
std::ios_base::binary | std::ios_base::in);

cereal::BinaryInputArchive archive(file);

if (!file.is_open()) {
throw FileShare::Errors::Config::NotFoundError(config_file.string());
}

archive(config);
// TODO: Need to validate config - if someone messes up the file, we could have problems
return config;
Expand Down
Loading
Loading