86 throw std::invalid_argument(
"protocol [" + protocol +
"] is not supported by peer");
92 const std::size_t header_size = std::strlen(
"ACC,") + 2 + protocol.size() + 4 + 5;
104 max_fragment_size = max_fragment_size * 6 / 8 - 1;
108 throw std::invalid_argument(
"no encoding available to encode app custom control message");
112 std::vector<std::string> control_messages;
114 for (std::size_t i = 0; i <
message.size(); i += max_fragment_size)
116 std::string fragment =
message.substr(i, max_fragment_size);
117 const bool lastfragment = (i + max_fragment_size) >=
message.size();
124 std::stringstream control_msg{};
125 control_msg <<
"ACC," << protocol <<
",";
126 control_msg << std::to_string(fragment.size()) <<
",";
127 control_msg << format;
130 control_msg <<
"," << fragment;
132 control_messages.emplace_back(control_msg.str());
134 return control_messages;
141 return {
"no supported protocols"};
144 std::stringstream
out;
179 if (parts.size() != 5 || parts[0] !=
"ACC")
181 throw parse_acc_message{
"Discarding malformed custom app control message"};
185 auto protocol = std::move(parts[1]);
186 auto length_str = std::move(parts[2]);
187 auto flags = std::move(parts[3]);
188 auto message = std::move(parts[4]);
190 bool base64Encoding =
false;
191 bool textEncoding =
false;
192 bool fragment =
false;
197 throw parse_acc_message{
"Discarding malformed custom app control message"};
200 for (
char const &c :
flags)
205 base64Encoding =
true;
214 throw parse_acc_message{
"Discarding malformed custom app control message. "
216 + std::to_string(c) +
"' in message found"};
220 if (textEncoding + base64Encoding != 1)
222 throw parse_acc_message{
"Discarding malformed custom app control message. "
223 "Unknown or no encoding flag in message found"};
231 throw parse_acc_message{
"custom app control framing error: message with different "
232 "protocol and previous fragmented message not finished"};
bool receive_message(const std::string &msg)
std::pair< std::string, std::string > get_message()
std::string encode(const V &data) const
size_t decode(void *data, size_t len, const std::string &str) const
void clear()
Clears the contents of the buffer.
void reset(const size_t min_capacity, const BufferFlags flags=BufAllocFlags::NO_FLAGS)
Resets the buffer with the specified minimum capacity and flags.
bool defined() const
Returns true if the buffer is not empty.
bool empty() const
Returns true if the buffer is empty.
void write(const T *data, const size_t size)
Write data to the buffer.
#define OPENVPN_EXCEPTION(C)
constexpr BufferFlags GROW(1u<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
STRING utf8_printable(const STRING &str, size_t max_len_flags)
auto join(const T &strings, const typename T::value_type &delim, const bool tail=false)
std::vector< T > split(const T &str, const typename T::value_type sep, const int maxsplit=-1)
bool parse_number(const char *str, T &retval, const bool nondigit_term=false)
std::string buf_to_string(const Buffer &buf)
bool supports_protocol(const std::string &protocol)
std::vector< std::string > supported_protocols
List of supported protocols.
int max_msg_size
Maximum size of each individual message/message fragment.
bool encoding_base64
Supports sending/receiving messages as base64 encoded binary.
std::vector< std::string > format_message(const std::string &protocol, const std::string &message)
Format a protocol string and a message into a properly packed series of message fragments.
bool operator==(const AppControlMessageConfig &other) const
bool encoding_binary
support sending binary as is as part of the ACC control channel message (not implemented yet)
void parse_flags(const std::string &flags)
static std::stringstream out