mirror of https://github.com/infosecn1nja/C3.git
103 lines
4.1 KiB
C++
103 lines
4.1 KiB
C++
#pragma once
|
|
|
|
namespace FSecure::C3::Core
|
|
{
|
|
// Forward declarations.
|
|
struct DeviceBridge;
|
|
|
|
// Typedefs and constants.
|
|
using ProceduresUnderlyingType = std::int8_t; ///< Underlying type for Procedure number field.
|
|
using SequenceNumberFieldUnderlyingType = std::uint32_t; /// Underlying type for Query/Response sequence numbers (including type bits = 2 bits).
|
|
|
|
/// Abstract class for all Queries.
|
|
struct BaseQuery
|
|
{
|
|
/// Enumeration for types of responses that can be requested for Queries.
|
|
enum class ResponseType : std::uint8_t
|
|
{
|
|
StatusBits, ///< Bit field: 00 - success, 01 - error, 10 - partial success, 11 - ACK.
|
|
StatusCode, ///< First - a bit field: 00 - success, 01 - error, 10 - success + extensions, 11 - partial success. Then StatusCode if the first bit-field was equal to 01 or 11.
|
|
ACK, ///< No status code nor bits. Just send back the ACK packet as soon as possible.
|
|
StatusCodePlusExtensions, ///< Same as StatusCode, but with extensions after bit-field, if the first bit field was 2 (e.g. iid of a newly added Interface) or after the StatusCode equal to 01 or 11. If status code doesn't require extensions (e.g. "No GDC") then extensions are omitted.
|
|
None = 255, ///< Do not respond.
|
|
};
|
|
|
|
/// Creates Query that is empty and should be filled then sent.
|
|
/// @param sender informs on the origin of message.
|
|
BaseQuery(std::weak_ptr<DeviceBridge> sender);
|
|
|
|
/// Creates Query that is empty and should be filled then sent.
|
|
/// @param responseType informs how recipient should react on message.
|
|
BaseQuery(ResponseType responseType = ResponseType::None);
|
|
|
|
/// Procedure number getter.
|
|
/// @return Procedure number.
|
|
/// @throws std::logic_error if not overriden.
|
|
virtual ProceduresUnderlyingType GetProcedureNumber() const { throw std::logic_error{ OBF("This method need to be overridden.") }; }
|
|
|
|
/// Deleted copy constructor.
|
|
BaseQuery(BaseQuery&) = delete;
|
|
|
|
/// Deleted copy assignment operator.
|
|
BaseQuery& operator=(BaseQuery&) = delete;
|
|
|
|
/// Default move constructor.
|
|
BaseQuery(BaseQuery&&) = default;
|
|
|
|
/// Default move assignment operator.
|
|
BaseQuery& operator=(BaseQuery&&) = default;
|
|
|
|
/// Response type setter.
|
|
/// @param responseType response type to set.
|
|
void SetResponseType(ResponseType responseType);
|
|
|
|
/// Compiles Query packet into a ByteVector.
|
|
/// @return Packet buffer.
|
|
virtual ByteVector ComposeQueryPacket() const = 0;
|
|
|
|
/// Sender Channel Getter.
|
|
/// @return Sender Channel or nullptr if this Query is yet about to be sent.
|
|
std::weak_ptr<DeviceBridge> GetSenderChannel();
|
|
|
|
/// Returns sequence Number.
|
|
auto GetSequenceNumber() const
|
|
{
|
|
return m_SequenceNumber;
|
|
}
|
|
|
|
protected:
|
|
/// Constructs Procedure header.
|
|
/// @return buffer containing composed header.
|
|
virtual ByteVector CompileProtocolHeader() const = 0;
|
|
|
|
/// Constructs Query packet header out of internal state and data.
|
|
/// @return Buffer containing the headers.
|
|
virtual ByteVector CompileQueryHeader() const;
|
|
|
|
private:
|
|
/// If true then this Query is just a copy of what was sent form remote Relay. If false then this is going to be send after filling up.
|
|
const bool m_ReceivedOrWillBeSent;
|
|
|
|
/// Underlying type for Query / Response sequence numbers(including type bits = 2 bits).
|
|
using SequenceNumberFieldUnderlyingType = std::uint32_t;
|
|
|
|
/// Number of bits sequence number occupy in the SequenceNumberType type.
|
|
static constexpr unsigned s_SequenceNumberBitLength = sizeof(SequenceNumberFieldUnderlyingType) * 8 - 2;
|
|
|
|
/// Sequence number
|
|
const SequenceNumberFieldUnderlyingType m_SequenceNumber;
|
|
|
|
/// sequence number generator (unique for every Query).
|
|
/// @return a unique number that can be used for a Query sequence number.
|
|
static SequenceNumberFieldUnderlyingType GenerateSequenceNumber();
|
|
|
|
std::uint8_t BuildSequenceNumberField(std::uint8_t statusBits) const;
|
|
|
|
/// Sender of this Query.Equals nullptr if this Query is yet about to be sent.
|
|
std::weak_ptr<DeviceBridge> m_SenderChannel;
|
|
|
|
/// Type of response requested for this Query.
|
|
ResponseType m_ResponseType;
|
|
};
|
|
}
|