Skip to content

Commit

Permalink
Redesign to enable TLS connection reusage and resigning of messages
Browse files Browse the repository at this point in the history
  • Loading branch information
durner committed Mar 15, 2024
1 parent 6b36ea6 commit 571ccb0
Show file tree
Hide file tree
Showing 31 changed files with 927 additions and 566 deletions.
6 changes: 3 additions & 3 deletions include/cloud/aws_resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ namespace anyblob {
//---------------------------------------------------------------------------
namespace cloud {
//---------------------------------------------------------------------------
/// Implements the AWS Resolver logic
/// Implements the AWS resolver logic
class AWSResolver : public network::Resolver {
/// The good mtu cache
std::unordered_map<unsigned, bool> _mtuCache;

public:
/// The constructor
explicit AWSResolver(unsigned entries);
explicit AWSResolver(unsigned cacheEntries);
/// The address resolving
virtual unsigned resolve(std::string hostname, std::string port, bool& reuse) override;
virtual const addrinfo* resolve(std::string hostname, std::string port, bool& reuse) override;
/// The destructor
virtual ~AWSResolver() noexcept = default;
};
Expand Down
66 changes: 66 additions & 0 deletions include/cloud/http.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once
#include "cloud/provider.hpp"
#include <cassert>
#include <string>
//---------------------------------------------------------------------------
// AnyBlob - Universal Cloud Object Storage Library
// Dominik Durner, 2024
//
// 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/.
// SPDX-License-Identifier: MPL-2.0
//---------------------------------------------------------------------------
namespace anyblob {
//---------------------------------------------------------------------------
namespace network {
class TaskedSendReceiver;
}; // namespace network
//---------------------------------------------------------------------------
namespace cloud {
//---------------------------------------------------------------------------
/// Implements a simple http request logic
class HTTP : public Provider {
public:
/// The settings for azure requests
struct Settings {
/// The container name
std::string hostname;
/// The port
uint32_t port;
};

private:
/// The settings
Settings _settings;

public:

/// The constructor
HTTP(const RemoteInfo& info) : _settings({info.endpoint, info.port}) {
assert(info.provider == Provider::CloudService::HTTP || info.provider == Provider::CloudService::HTTPS);
_type = info.provider;
}

private:
/// Get the settings
[[nodiscard]] inline Settings getSettings() { return _settings; }

/// Builds the http request for downloading a blob or listing the directory
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> getRequest(const std::string& filePath, const std::pair<uint64_t, uint64_t>& range) const override;
/// Builds the http request for putting objects without the object data itself
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> putRequest(const std::string& filePath, std::string_view object) const override;
// Builds the http request for deleting an objects
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> deleteRequest(const std::string& filePath) const override;

/// Get the address of the server
[[nodiscard]] std::string getAddress() const override;
/// Get the port of the server
[[nodiscard]] uint32_t getPort() const override;
/// Get the instance details
[[nodiscard]] Provider::Instance getInstanceDetails(network::TaskedSendReceiver& sendReceiver) override;

friend Provider;
};
//---------------------------------------------------------------------------
} // namespace cloud
} // namespace anyblob
35 changes: 20 additions & 15 deletions include/cloud/provider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,22 @@ namespace cloud {
class Provider {
public:
/// The remote prefixes count
static constexpr unsigned remoteFileCount = 6;
static constexpr unsigned remoteFileCount = 8;
/// The remote prefixes
static constexpr std::string_view remoteFile[] = {"s3://", "azure://", "gcp://", "oci://", "ibm://", "minio://"};
static constexpr std::string_view remoteFile[] = { "http://", "https://", "s3://", "azure://", "gcp://", "oci://", "ibm://", "minio://"};
/// Are we currently testing the provdiers
static bool testEnviornment;

/// The cloud service enum
enum class CloudService : uint8_t {
AWS = 0,
Azure = 1,
GCP = 2,
Oracle = 3,
IBM = 4,
MinIO = 5,
HTTP = 0,
HTTPS = 1,
AWS = 2,
Azure = 3,
GCP = 4,
Oracle = 5,
IBM = 6,
MinIO = 7,
Local = 255
};

Expand Down Expand Up @@ -76,7 +78,14 @@ class Provider {
};

protected:
/// The type
CloudService _type;
/// Initialize secret
virtual void initSecret(network::TaskedSendReceiver& /*sendReceiver*/) {}
/// Get a local copy of the global secret
virtual void getSecret() {}

public:
/// Builds the http request for downloading a blob or listing a directory
[[nodiscard]] virtual std::unique_ptr<utils::DataVector<uint8_t>> getRequest(const std::string& filePath, const std::pair<uint64_t, uint64_t>& range) const = 0;
/// Builds the http request for putting an object without the actual data (header only according to the data and length provided)
Expand All @@ -98,13 +107,9 @@ class Provider {
[[nodiscard]] virtual std::unique_ptr<utils::DataVector<uint8_t>> createMultiPartRequest(const std::string& /*filePath*/) const;
/// Builds the http request for completing multipart put objects
[[nodiscard]] virtual std::unique_ptr<utils::DataVector<uint8_t>> completeMultiPartRequest(const std::string& /*filePath*/, std::string_view /*uploadId*/, const std::vector<std::string>& /*etags*/, std::string& /*eTagsContent*/) const;
/// Supports resigning?
[[nodiscard]] virtual bool supportsResigning() const { return false; }

/// Initialize secret
virtual void initSecret(network::TaskedSendReceiver& /*sendReceiver*/) {}
/// Get a local copy of the global secret
virtual void getSecret() {}

public:
/// The destructor
virtual ~Provider() noexcept = default;
/// Gets the cloud provider type
Expand All @@ -125,7 +130,7 @@ class Provider {
[[nodiscard]] static std::vector<std::string> parseCSVRow(std::string_view body);

/// Create a provider (keyId is access email for GCP/Azure)
[[nodiscard]] static std::unique_ptr<Provider> makeProvider(const std::string& filepath, bool https = true, const std::string& keyId = "", const std::string& keyFile = "", network::TaskedSendReceiver* sendReceiver = nullptr);
[[nodiscard]] static std::unique_ptr<Provider> makeProvider(const std::string& filepath, bool https = false, const std::string& keyId = "", const std::string& keyFile = "", network::TaskedSendReceiver* sendReceiver = nullptr);

/// Init the resolver for specific provider
virtual void initResolver(network::TaskedSendReceiver& /*sendReceiver*/) {}
Expand Down
118 changes: 118 additions & 0 deletions include/network/connection_manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#pragma once
#include "network/resolver.hpp"
#include <cassert>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <liburing.h>
//---------------------------------------------------------------------------
// AnyBlob - Universal Cloud Object Storage Library
// Dominik Durner, 2024
//
// 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/.
// SPDX-License-Identifier: MPL-2.0
//---------------------------------------------------------------------------
namespace anyblob {
namespace network {
//---------------------------------------------------------------------------
class TLSConnection;
class TLSContext;
//---------------------------------------------------------------------------
// This class acts as the connection enabler, closer, and main
// cache for sockets and their optional tls connection.
// We further add the DNS resolution to the connection manager.
class ConnectionManager {
public:
/// The tcp settings
struct TCPSettings {
/// flag for nonBlocking
int nonBlocking = 1;
/// flag for noDelay
int noDelay = 0;
/// flag for recv no wait
int recvNoWait = 0;
/// flag for keepAlive
int keepAlive = 1;
/// time for tcp keepIdle
int keepIdle = 1;
/// time for tcp keepIntvl
int keepIntvl = 1;
/// probe count
int keepCnt = 1;
/// recv buffer for tcp
int recvBuffer = 0;
/// Maximum segment size
int mss = 0;
/// Reuse port
int reusePorts = 0;
/// Lingering of tcp packets
int linger = 1;
/// The timeout in usec
int timeout = 500 * 1000;
/// Reuse sockets
int reuse = 0;
/// The kernel timeout parameter
__kernel_timespec kernelTimeout;

TCPSettings() {
kernelTimeout.tv_sec = 0;
kernelTimeout.tv_nsec = timeout * 1000;
}
};

/// The fd socket entry
struct SocketEntry {
/// The optional tls connection
std::unique_ptr<TLSConnection> tls;
/// The fd
int32_t fd;
/// The port
unsigned port;
/// The hostname
std::string hostname;

SocketEntry(int32_t fd, std::string hostname, unsigned port, std::unique_ptr<TLSConnection> tls);
};

private:
/// The socket wrapper
std::unique_ptr<IOUringSocket> _socketWrapper;
/// The active sockets
std::unordered_map<int32_t, std::unique_ptr<SocketEntry>> _fdSockets;
/// The fd socket cache, uses hostname as key
std::unordered_multimap<std::string, std::unique_ptr<SocketEntry>> _fdCache;
/// Resolver
std::unordered_map<std::string, std::unique_ptr<Resolver>> _resolverCache;
/// The tls context
std::unique_ptr<network::TLSContext> _context;

public:
/// The constructor
explicit ConnectionManager(unsigned uringEntries, unsigned resolverCacheEntries);
/// The destructor
~ConnectionManager();

/// Creates a new socket connection
[[nodiscard]] int32_t connect(std::string hostname, uint32_t port, bool tls, const TCPSettings& tcpSettings, bool useCache = true, int retryLimit = 16);
/// Disconnects the socket
void disconnect(int32_t fd, std::string hostname = "", uint32_t port = 0, const TCPSettings* tcpSettings = nullptr, uint64_t bytes = 0, bool forceShutdown = false);

/// Add resolver
void addResolver(const std::string& hostname, std::unique_ptr<Resolver> resolver);
/// Checks for a timeout
bool checkTimeout(int fd, const TCPSettings& settings);

/// Get the socket
IOUringSocket& getSocketConnection() {
assert(_socketWrapper);
return *_socketWrapper.get();
}

/// Get the tls connection of the fd
TLSConnection* getTLSConnection(int32_t fd);
};
//---------------------------------------------------------------------------
}; // namespace network
}; // namespace anyblob
6 changes: 3 additions & 3 deletions include/network/http_message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ struct HTTPMessage : public MessageTask {
std::unique_ptr<HttpHelper::Info> info;

/// The constructor
HTTPMessage(OriginalMessage* sendingMessage);
HTTPMessage(OriginalMessage* sendingMessage, ConnectionManager::TCPSettings& tcpSettings, uint32_t chunkSize);
/// The destructor
~HTTPMessage() override = default;
/// The message excecute callback
MessageState execute(IOUringSocket& socket) override;
MessageState execute(ConnectionManager& connectionManager) override;
/// Reset for restart
void reset(IOUringSocket& socket, bool aborted);
void reset(ConnectionManager& connectionManager, bool aborted);
};
//---------------------------------------------------------------------------
} // namespace network
Expand Down
12 changes: 7 additions & 5 deletions include/network/https_message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ namespace network {
//---------------------------------------------------------------------------
/// Implements a https message roundtrip
struct HTTPSMessage : public HTTPMessage {
/// The TLSLayer
std::unique_ptr<TLSConnection> tlsLayer;
/// The tls layer
TLSConnection* tlsLayer;
/// The fd
int32_t fd;

/// The constructor
HTTPSMessage(OriginalMessage* sendingMessage);
HTTPSMessage(OriginalMessage* sendingMessage, ConnectionManager::TCPSettings& tcpSettings, uint32_t chunksize);
/// The destructor
~HTTPSMessage() override = default;
/// The message excecute callback
MessageState execute(IOUringSocket& socket) override;
MessageState execute(ConnectionManager& connectionManager) override;
/// Reset for restart
void reset(IOUringSocket& socket, bool aborted);
void reset(ConnectionManager& socket, bool aborted);
};
//---------------------------------------------------------------------------
} // namespace network
Expand Down
Loading

0 comments on commit 571ccb0

Please sign in to comment.